{"record":{"id":"6b49fb0bce8e87b3","repo":"tailscale/tailscale","slug":"key-hex-has-the-wrong-size-got-d-want-d","errorCode":null,"errorMessage":"key hex has the wrong size, got %d want %d","messagePattern":"key hex has the wrong size, got (.+?) want (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"types/key/util.go","lineNumber":76,"sourceCode":"\tdst = append(dst, prefix...)\n\tdst = hex.AppendEncode(dst, key)\n\treturn dst\n}\n\n// parseHex decodes a key string of the form \"<prefix><hex string>\"\n// into out. The prefix must match, and the decoded base64 must fit\n// exactly into out.\n//\n// Note the errors in this function deliberately do not echo the\n// contents of in, because it might be a private key or part of a\n// private key.\nfunc parseHex(out []byte, in, prefix mem.RO) error {\n\tif !mem.HasPrefix(in, prefix) {\n\t\treturn fmt.Errorf(\"key hex string doesn't have expected type prefix %s\", prefix.StringCopy())\n\t}\n\tin = in.SliceFrom(prefix.Len())\n\tif want := len(out) * 2; in.Len() != want {\n\t\treturn fmt.Errorf(\"key hex has the wrong size, got %d want %d\", in.Len(), want)\n\t}\n\tfor i := range out {\n\t\ta, ok1 := fromHexChar(in.At(i*2 + 0))\n\t\tb, ok2 := fromHexChar(in.At(i*2 + 1))\n\t\tif !ok1 || !ok2 {\n\t\t\treturn errors.New(\"invalid hex character in key\")\n\t\t}\n\t\tout[i] = (a << 4) | b\n\t}\n\treturn nil\n}\n\n// fromHexChar converts a hex character into its value and a success flag.\nfunc fromHexChar(c byte) (byte, bool) {\n\tswitch {\n\tcase '0' <= c && c <= '9':\n\t\treturn c - '0', true\n\tcase 'a' <= c && c <= 'f':","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/types/key/util.go#L58-L94","documentation":"parseHex reports that after stripping the type prefix, the remaining hex string decodes to a byte count that doesn't exactly fill the destination key array (got vs want sizes in the %d operands). Length is the fault, not content — e.g. a node key hex body that is not 64 characters.","triggerScenarios":"Thrown at types/key/util.go:76 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use the key's String()/MarshalText output verbatim; it always emits the exact hex length","Regenerate the key material if stored data has the wrong size","Avoid hand-truncating or concatenating hex key strings"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}