{"record":{"id":"0aba34834545a098","repo":"syncthing/syncthing","slug":"q-device-id-invalid-incorrect-length","errorCode":null,"errorMessage":"%q: device ID invalid: incorrect length","messagePattern":"%q: device ID invalid: incorrect length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/protocol/deviceid.go","lineNumber":151,"sourceCode":"\t\t*n = EmptyDeviceID\n\t\treturn nil\n\tcase 56:\n\t\t// New style, with check digits\n\t\tid, err = unluhnify(id)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfallthrough\n\tcase 52:\n\t\t// Old style, no check digits\n\t\tdec, err := base32.StdEncoding.DecodeString(id + \"====\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcopy(n[:], dec)\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"%q: device ID invalid: incorrect length\", bs)\n\t}\n}\n\nfunc (*DeviceID) ProtoSize() int {\n\t// Used by protobuf marshaller.\n\treturn DeviceIDLength\n}\n\nfunc (n *DeviceID) MarshalTo(bs []byte) (int, error) {\n\t// Used by protobuf marshaller.\n\tif len(bs) < DeviceIDLength {\n\t\treturn 0, errors.New(\"destination too short\")\n\t}\n\tcopy(bs, (*n)[:])\n\treturn DeviceIDLength, nil\n}\n\nfunc (n *DeviceID) Unmarshal(bs []byte) error {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/syncthing/syncthing/blob/058bcd7334839663cf569501d3ac539034d45cb5/lib/protocol/deviceid.go#L133-L169","documentation":"DeviceID.UnmarshalText/String parse rejects a candidate device ID whose length matches none of the supported encodings: 63 chars (new style, 56 + 7 dashes), 59 (with trailing checksum digit variant), or 52 (old style, raw base32). The input is simply not a device ID in any accepted format — most commonly truncated copy-paste or stray characters.","triggerScenarios":"protocol.DeviceID from user input; config load with a <device id=...> attribute that is truncated or contains extra whitespace/newlines; passing a 44-char base32 key or a SHA-256 hex string instead of the 63-char formatted ID.","commonSituations":"Copy-pasting a device ID missing the last group; pasting a certificate fingerprint (hex) instead of the Syncthing device ID; whitespace or quotes accidentally included when scripting config edits.","solutions":["Re-copy the full device ID from the remote's 'Actions > Show ID' screen — it must be 63 characters including dashes.","Strip whitespace/newlines from the input before parsing.","Verify you are not passing a certificate SHA256 fingerprint or API key instead of the device ID.","Validate length and charset (A-Z2-7 plus dashes) before storing it in config."],"exampleFix":"// before\nid, err := protocol.DeviceIDFromString(userInput)\n\n// after\nclean := strings.TrimSpace(strings.Join(strings.Fields(userInput), \"\"))\nif len(clean) != 63 && len(clean) != 52 {\n    return fmt.Errorf(\"expected 63-char device ID, got %d chars\", len(clean))\n}\nid, err := protocol.DeviceIDFromString(clean)","handlingStrategy":"validation","validationCode":"// Validate shape before parsing a device ID from user input\nfunc looksLikeDeviceID(s string) bool {\n    s = strings.ReplaceAll(strings.TrimSpace(s), \"-\", \"\")\n    for _, c := range s {\n        if !(c >= 'A' && c <= 'Z' || c >= '2' && c <= '7') { return false }\n    }\n    return len(s) == 52 || len(s) == 56 // old style raw, or new style with check digits\n}","typeGuard":null,"tryCatchPattern":"id, err := protocol.DeviceIDFromString(input)\nif err != nil {\n    // covers 'incorrect length' plus check-digit/charset errors;\n    // re-prompt the user to paste the full 63-char ID (QR code preferred)\n    return fmt.Errorf(\"invalid device ID %q: %w\", input, err)\n}","preventionTips":["Always copy device IDs from the Show ID dialog or QR code.","Strip whitespace/newlines before storing or parsing IDs.","Validate length (63 chars with dashes) and charset (A-Z, 2-7) in config forms."],"tags":["protocol","device-id","validation","go"],"backgroundTag":null,"analyzedSha":"058bcd7334839663cf569501d3ac539034d45cb5","analyzedAt":"2026-08-15T07:53:43.174Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}