grpc/grpc-go · error

invalid code

Error message

invalid code: %q

What it means

Returned by codes.Code.UnmarshalJSON when the JSON input is a string token (with surrounding quotes) that does not match any known canonical gRPC code name in the strToCode map (OK, CANCELLED, UNKNOWN, INVALID_ARGUMENT, DEADLINE_EXCEEDED, NOT_FOUND, ALREADY_EXISTS, PERMISSION_DENIED, RESOURCE_EXHAUSTED, FAILED_PRECONDITION, ABORTED, OUT_OF_RANGE, UNIMPLEMENTED, INTERNAL, UNAVAILABLE, DATA_LOSS, UNAUTHENTICATED).

Solutions

  1. Use the exact canonical UPPER_SNAKE_CASE name from the strToCode map (note CANCELLED is British spelling with two L's).
  2. Send numeric codes as bare JSON numbers (no quotes) within [0,16] instead of strings.
  3. Validate/gateway external string values against codes.Code.String() or a known enum before producing the JSON.

Example fix

// before
var c codes.Code
json.Unmarshal([]byte(`"CANCEL"`), &c) // invalid code: "CANCEL" (missing an L)

// after
var c codes.Code
json.Unmarshal([]byte(`"CANCELLED"`), &c) // canonical name
Defensive patterns

Strategy: validation

Validate before calling

var validCodeNames = map[string]bool{
    `"OK"`: true, `"CANCELLED"`: true, `"UNKNOWN"`: true, `"INVALID_ARGUMENT"`: true,
    `"DEADLINE_EXCEEDED"`: true, `"NOT_FOUND"`: true, `"ALREADY_EXISTS"`: true,
    `"PERMISSION_DENIED"`: true, `"RESOURCE_EXHAUSTED"`: true, `"FAILED_PRECONDITION"`: true,
    `"ABORTED"`: true, `"OUT_OF_RANGE"`: true, `"UNIMPLEMENTED"`: true, `"INTERNAL"`: true,
    `"UNAVAILABLE"`: true, `"DATA_LOSS"`: true, `"UNAUTHENTICATED"`: true,
}
func isValidCodeJSONToken(b []byte) bool {
    _, ok1 := strconv.ParseUint(string(b), 10, 32) // numeric ok if < 17
    return ok1 == nil || validCodeNames[string(b)]
}

Type guard

func isCanonicalCodeName(s string) bool {
    return validCodeNames[strconv.Quote(s)]
}

Prevention

When it happens

Trigger: Unmarshaling JSON containing a quoted string that is not one of the 17 recognized code names — e.g. "FOO", "CANCEL" (missing an L; the canonical name is CANCELLED), "not_found" (lowercase), or "5" (a number inside quotes, which ParseUint rejects due to the quotes and strToCode also rejects).

Common situations: A typo in the code name, using lowercase instead of UPPER_SNAKE_CASE, using a different naming convention (e.g. HTTP status text like "NOT_FOUND" is valid but "Not Found" is not), or a non-gRPC service emitting its own string error identifiers into the same field.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/6ec3595a8a476f04. Report an issue: GitHub.

Appendix: source

Thrown at codes/codes.go:249

	}
	if c == nil {
		return fmt.Errorf("nil receiver passed to UnmarshalJSON")
	}

	if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
		if ci >= _maxCode {
			return fmt.Errorf("invalid code: %d", ci)
		}

		*c = Code(ci)
		return nil
	}

	if jc, ok := strToCode[string(b)]; ok {
		*c = jc
		return nil
	}
	return fmt.Errorf("invalid code: %q", string(b))
}

View on GitHub (pinned to 0c51461d27)