{"record":{"id":"edd71d5832300ac3","repo":"restic/restic","slug":"error-parsing-generic-attribute-for-s-v","errorCode":null,"errorMessage":"error parsing generic attribute for: %s : %v","messagePattern":"error parsing generic attribute for: (.+?) : (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/fs/node_windows.go","lineNumber":198,"sourceCode":"\t\t\teas = append(eas, extendedAttribute{Name: oldEA.Name, Value: nil})\n\t\t}\n\t}\n\n\tif err = fsetEA(fileHandle, eas); err != nil {\n\t\treturn errors.Errorf(\"set EA failed for path %v, with: %v\", path, err)\n\t}\n\treturn nil\n}\n\n// restoreGenericAttributes restores generic attributes for Windows\nfunc nodeRestoreGenericAttributes(node *data.Node, path string, warn func(msg string)) (err error) {\n\tif len(node.GenericAttributes) == 0 {\n\t\treturn nil\n\t}\n\tvar errs []error\n\twindowsAttributes, unknownAttribs, err := genericAttributesToWindowsAttrs(node.GenericAttributes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing generic attribute for: %s : %v\", path, err)\n\t}\n\tif windowsAttributes.CreationTime != nil {\n\t\tif err := restoreCreationTime(path, windowsAttributes.CreationTime); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"error restoring creation time for: %s : %v\", path, err))\n\t\t}\n\t}\n\tif windowsAttributes.FileAttributes != nil {\n\t\tif err := restoreFileAttributes(path, windowsAttributes.FileAttributes); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"error restoring file attributes for: %s : %v\", path, err))\n\t\t}\n\t}\n\tif windowsAttributes.SecurityDescriptor != nil {\n\t\tif err := setSecurityDescriptor(path, windowsAttributes.SecurityDescriptor); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"error restoring security descriptor for: %s : %v\", path, err))\n\t\t}\n\t}\n\n\tdata.HandleUnknownGenericAttributesFound(unknownAttribs, warn)","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/restic/restic/blob/a80be1478a4c537f8396e0db2b05120aa78f11e0/internal/fs/node_windows.go#L180-L216","documentation":"nodeRestoreGenericAttributes (Windows) converts the node's stored generic attributes to Windows attributes via GenericAttributesToOSAttrs and wraps a parse failure. The parse step decodes each generic attribute's JSON payload (creation time, file attributes, security descriptor) into the typed WindowsAttributes struct, so failure means the stored data for an attribute did not match the expected type. Unlike the per-attribute restore failures below, a parse error aborts generic attribute restoration for this node entirely.","triggerScenarios":"The snapshot's node.GenericAttributes contains a Windows attribute whose JSON payload is not decodable into the expected Go type (e.g. creation time stored as a string instead of a number after a schema change), or a value out of range (file attribute constant that overflows the destination type). Corrupted snapshot JSON from repo bit rot or a hand-edited snapshot produces the same error.","commonSituations":"Snapshots created by an older/newer restic version whose generic attribute encoding differs; repo data corruption (run restic check); snapshots restored after partial memory or disk failures during backup.","solutions":["Run `restic check --read-data` to rule out repository corruption.","Restore with a restic version at least as new as the one that created the snapshot (generic attribute formats evolved across 0.16/0.17).","If the attributes are not needed, restore without generic attributes (restic skips them when absent; a parse failure only loses metadata, not file contents).","Re-create the snapshot with the current restic version if the source data is still available."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import \"encoding/json\"\n\n// best-effort pre-check that stored generic attributes decode:\nfunc genericAttrsParseable(raw map[data.GenericAttributeType]json.RawMessage) bool {\n\tfor k, v := range raw {\n\t\tif !json.Valid(v) {\n\t\t\t_ = k\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"err := nodeRestoreGenericAttributes(node, path, warn)\nif err != nil {\n\t// contents already restored; only Windows metadata is lost\n\twarnf(\"generic attributes for %s skipped: %v\", path, err)\n}","preventionTips":["Run `restic check --read-data` regularly so corruption is caught before restore.","Keep the restoring restic at least as new as the one that wrote the snapshots.","Treat generic-attribute failures as metadata loss, not data loss; verify file contents separately."],"tags":["go","windows","generic-attributes","json","restore","version-mismatch","corruption"],"backgroundTag":null,"analyzedSha":"a80be1478a4c537f8396e0db2b05120aa78f11e0","analyzedAt":"2026-08-15T15:30:29.928Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}