Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report] InvokeDeviceMethodAsync fails with error code 400000 #3472

Closed
williamiwell opened this issue Sep 26, 2024 · 4 comments
Closed
Labels
bug Something isn't working.

Comments

@williamiwell
Copy link

williamiwell commented Sep 26, 2024

Context

  • OS, version, SKU and CPU architecture used: OSX/Ubuntu20.x (Windows 10 Desktop x64, Ubuntu 15.04 x86, Windows 10 IoT Core arm32, etc.)
  • Application's .NET Target Framework : dotnet 8 (See https://docs.microsoft.com/en-us/dotnet/standard/frameworks. E.g. netcoreapp2.1, net451, uap10.0, xamarin)
  • Device: - cloud (Laptop, Raspberry PI3, Android APIv25 etc.)
  • SDK version used: microsoft.azure.devices/1.39.1 (Please include the NuGet package version for all involved components)

Description of the issue

We use IotHub to send messages from our cloud to edge devices, using the InvokeDeviceMethodAsync method. This worked fine until 25-September-2024 19:00 UTC, but now we receive error code 400000. We can't find any information about this code, it's not listed in the common error codes docs.

We are using the latests nuget package: microsoft.azure.devices/1.39.1. The devices are online and are able to send device to cloud messages.

Any idea what is going on and if we can resolve this or that is related to an IotEdge issue?
Our IotHub is located in West Europa.

Code sample exhibiting the issue

var serviceClient = iotHubFactory.CreateServiceClient();
response = await serviceClient.InvokeDeviceMethodAsync(moduleId, cloudToDeviceMethod);

this throws the exception below:

{"Message":"{\"errorCode\":400000,\"message\":\"400\",\"trackingId\":\"46A2268BA66A4093B44234E2B56A6464-G2:-TimeStamp:2024-09-26T07:52:28.960569771Z\",\"timestampUtc\":\"2024-09-26T07:52:28.960569771Z\",\"info\":null}","ExceptionMessage":""}
@williamiwell williamiwell added the bug Something isn't working. label Sep 26, 2024
@timtay-microsoft
Copy link
Member

Can you share a bit more about the direct method payload you are sending?

@williamiwell
Copy link
Author

The payload is a json with protobuf base64 string, for example

{
"byteArrayBase64": "CiENAAB6RBIMCPKt1rcGEKiz05sBGgwIrq7WtwYQqLPTmwE="
}

The code below is used to set the payload:

var payloadJson = JsonConvert.SerializeObject(payload, jsonSerializerSettings);
cloudToDeviceMethod.SetPayloadJson(payloadJson);

@JustZeus
Copy link

JustZeus commented Oct 14, 2024

Hello @williamiwell I was able to reproduce the issue and obtain the same error code.

Your call is missing a parameter, since I believe you are trying to invoke an edge custom module direct method, please add both the deviceId and the moduleId as parameters, this will enable the private function:

private static Uri GetModuleMethodUri(string deviceId, string moduleId)

to create the appropriate URL for the request to the API and call the method invocation for IoT edge module as mentioned in: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-direct-methods#method-invocation-for-iot-edge-modules

Following the function expected parameters to invoke an edge custom module direct method,
Azure/azure-iot-sdk-csharp/blob/main/iothub/service/src/Messaging/ServiceClient.cs#L493

your call to the function should be similar to: (invoking the $edgeAgent ping method for reference, you can replace it with your custom module identity).

var methodInvocation = new CloudToDeviceMethod("ping") { ResponseTimeout = TimeSpan.FromSeconds(60), }; methodInvocation.SetPayloadJson("null");

CloudToDeviceMethodResult response = await serviceClient.InvokeDeviceMethodAsync(deviceId, "$edgeAgent", methodInvocation);

Executing this reference code I obtain from the CLI application:

Response status: 200, payload: null Press Enter to exit.

Hope the information is helpful, kind regards!

@williamiwell
Copy link
Author

I can confirm that using two parameters works.

 // this works
 response = await serviceClient.InvokeDeviceMethodAsync(deviceId, moduleName, cloudToDeviceMethod);
// the method below fails with a 400000 error code. 
var moduleId = $"{deviceId}/modules/{moduleName}";
response = await serviceClient.InvokeDeviceMethodAsync(moduleId, cloudToDeviceMethod);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working.
Projects
None yet
Development

No branches or pull requests

3 participants