{"record":{"id":"0a2f12cb57714676","repo":"hashicorp/nomad","slug":"ack-error","errorCode":null,"errorMessage":"ack.Error","messagePattern":"ack\\.Error","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/rpc.go","lineNumber":280,"sourceCode":"\tdecoder := codec.NewDecoder(conn, structs.MsgpackHandle)\n\theader := structs.StreamingRpcHeader{\n\t\tMethod: method,\n\t}\n\tif err := encoder.Encode(header); err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\t// Wait for the acknowledgement\n\tvar ack structs.StreamingRpcAck\n\tif err := decoder.Decode(&ack); err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\tif ack.Error != \"\" {\n\t\tconn.Close()\n\t\treturn nil, errors.New(ack.Error)\n\t}\n\n\treturn conn, nil\n}\n\n// setupClientRpc is used to setup the Client's RPC endpoints\nfunc (c *Client) setupClientRpc(rpcs map[string]any) {\n\t// Create the RPC Server\n\tc.rpcServer = rpc.NewServer()\n\n\t// Initialize the RPC handlers\n\tif rpcs != nil {\n\t\t// override RPCs\n\t\tfor name, rpc := range rpcs {\n\t\t\tc.rpcServer.RegisterName(name, rpc)\n\t\t}\n\t} else {\n\t\tc.endpoints.ClientStats = &ClientStats{c}","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/rpc.go#L262-L298","documentation":"streamingRpcConn converts the ack.Error string returned in the streaming RPC handshake acknowledgment into a Go error and closes the connection. It means the remote side (client or server) rejected the streaming RPC setup and returned an error message in the ack frame.","triggerScenarios":"Establishing a streaming RPC via RemoteStreamingRpcHandler where the remote peer's handshake ack carries a non-empty Error field — e.g. unknown RPC method, auth/ACL rejection, or the remote node refusing the connection setup.","commonSituations":"Version skew so the requested streaming endpoint doesn't exist remotely, ACL tokens lacking permission for the streaming RPC, or the remote node being down/draining.","solutions":["Check the ack.Error text (it is the remote's message) and fix the underlying cause","Verify both nodes run compatible Nomad versions for the streaming endpoint","Ensure the ACL token used has the required capabilities","Confirm the remote node/agent is healthy and reachable"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"conn, err := streamingRpcConn(client, method)\nif err != nil {\n    // err.Error() carries the remote ack.Error text\n    log.Warnf(\"streaming RPC rejected: %v\", err)\n    return fallbackToNonStreaming()\n}","preventionTips":["Keep client and server Nomad versions compatible","Check the ack error text to diagnose the remote-side rejection","Verify ACL capabilities for the streaming method before dialing","Confirm node health/connectivity before establishing streaming RPCs"],"tags":["go","rpc","network"],"backgroundTag":"rpc-handshake-rejected","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}