{"record":{"id":"aeba0839eb54b356","repo":"hashicorp/nomad","slug":"s-d-s","errorCode":null,"errorMessage":"%s%d,%s","messagePattern":"%s%d,%s","errorType":"http","errorClass":"errRPCCodedErrorPrefix","httpStatus":null,"severity":"error","filePath":"nomad/structs/errors.go","lineNumber":211,"sourceCode":"// unable to determine the version of a node.\nfunc IsErrUnknownNomadVersion(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), errUnknownNomadVersion)\n}\n\n// IsErrNodeLacksRpc returns whether error is due to a Nomad server being\n// unable to connect to a client node because the client is too old (pre-v0.8).\nfunc IsErrNodeLacksRpc(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), errNodeLacksRpc)\n}\n\nfunc IsErrNoSuchFileOrDirectory(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"no such file or directory\")\n}\n\n// NewErrRPCCoded wraps an RPC error with a code to be converted to HTTP status\n// code\nfunc NewErrRPCCoded(code int, msg string) error {\n\treturn fmt.Errorf(\"%s%d,%s\", errRPCCodedErrorPrefix, code, msg)\n}\n\n// NewErrRPCCodedf wraps an RPC error with a code to be converted to HTTP\n// status code.\nfunc NewErrRPCCodedf(code int, format string, args ...any) error {\n\tmsg := fmt.Sprintf(format, args...)\n\treturn fmt.Errorf(\"%s%d,%s\", errRPCCodedErrorPrefix, code, msg)\n}\n\n// CodeFromRPCCodedErr returns the code and message of error if it's an RPC error\n// created through NewErrRPCCoded function.  Returns `ok` false if error is not\n// an rpc error\nfunc CodeFromRPCCodedErr(err error) (code int, msg string, ok bool) {\n\tif err == nil || !strings.HasPrefix(err.Error(), errRPCCodedErrorPrefix) {\n\t\treturn 0, \"\", false\n\t}\n\n\theaderLen := len(errRPCCodedErrorPrefix)","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/errors.go#L193-L229","documentation":"NewErrRPCCoded wraps an error message with a numeric RPC status code using the internal errRPCCodedErrorPrefix ('%s%d,%s'), so HTTP handlers can later decode the code into an HTTP status via CodeFromRPCCodedErr. It is Nomad's mechanism to carry structured status (e.g. 403 ACL denied, 400 bad params) from RPC endpoints to the HTTP layer.","triggerScenarios":"Calling NewErrRPCCoded(code, msg) with a non-200 code; called from ACL policy write/delete paths (UpsertPolicies, DeletePolicies) and via aclDisabled when the agent has ACLs disabled but an authenticated request arrives, or Apply/Profile fail with a coded condition.","commonSituations":"POSTing ACL policies to a cluster where ACLs are not enabled (aclDisabled path returns a coded 400/401); malformed policy submissions rejected with 400; permission errors surfaced as coded 403s.","solutions":["Inspect the embedded code with structs.CodeFromRPCCodedErr(err) and branch on the HTTP-equivalent status","If code is 401/403, supply a valid Nomad token via SetSecretID/NOMAD_TOKEN","If ACLs are disabled on the server, stop sending ACL credentials or enable ACLs","If 400, validate the policy payload (Name, Rules HCL) before submission"],"exampleFix":"// before\nif _, err := client.ACLPolicies().Upsert(p, nil); err != nil { return err }\n// after\nif _, err := client.ACLPolicies().Upsert(p, nil); err != nil {\n    if code, msg, ok := structs.CodeFromRPCCodedErr(err); ok {\n        return fmt.Errorf(\"acl rpc failed (code %d): %s\", code, msg)\n    }\n    return err\n}","handlingStrategy":"type-guard","validationCode":"// go: check ACLs are enabled before ACL RPCs\nagentInfo, err := client.Agent().Self()\nif err == nil {\n    cfg := agentInfo.Config.ACLConfig\n    if cfg != nil && !cfg.Enabled { return errors.New(\"ACLs are not enabled on this cluster\") }\n}","typeGuard":"func IsRPCCoded(err error) (int, string, bool) { return structs.CodeFromRPCCodedErr(err) }","tryCatchPattern":"if _, err := client.ACLPolicies().Upsert(p, nil); err != nil {\n    if code, msg, ok := structs.CodeFromRPCCodedErr(err); ok {\n        switch code {\n        case 401, 403: /* fix token */\n        default: return fmt.Errorf(\"rpc %d: %s\", code, msg)\n        }\n    }\n    return err\n}","preventionTips":["Always attach a secret token when ACLs are enabled","Decode coded errors instead of string-matching messages","Validate policy payloads client-side before writes"],"tags":["nomad","rpc","status-code","acl"],"backgroundTag":"rpc-status-error","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"}