{"record":{"id":"3c3d769f17012400","repo":"benbjohnson/litestream","slug":"replica-client-does-not-support-v0-3-x-restore","errorCode":null,"errorMessage":"replica client does not support v0.3.x restore","messagePattern":"replica client does not support v0\\.3\\.x restore","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica.go","lineNumber":1070,"sourceCode":"\t\t}\n\t\tif _, err := closeLevel(nil); err != nil {\n\t\t\treturn currentTXID, err\n\t\t}\n\n\t\t// If we made progress at this level, restart from level 1.\n\t\tif currentTXID > afterTXID {\n\t\t\treturn currentTXID, nil\n\t\t}\n\t}\n\n\treturn currentTXID, nil\n}\n\n// RestoreV3 restores from a v0.3.x format backup.\nfunc (r *Replica) RestoreV3(ctx context.Context, opt RestoreOptions) error {\n\tclient, ok := r.Client.(ReplicaClientV3)\n\tif !ok {\n\t\treturn fmt.Errorf(\"replica client does not support v0.3.x restore\")\n\t}\n\n\t// Validate options.\n\tif opt.OutputPath == \"\" {\n\t\treturn fmt.Errorf(\"output path required\")\n\t} else if opt.IntegrityCheck != IntegrityCheckNone && opt.IntegrityCheck != IntegrityCheckQuick && opt.IntegrityCheck != IntegrityCheckFull {\n\t\treturn fmt.Errorf(\"unsupported integrity check mode: %d\", opt.IntegrityCheck)\n\t}\n\n\t// Ensure output path does not already exist.\n\tif _, err := os.Stat(opt.OutputPath); err == nil {\n\t\treturn fmt.Errorf(\"cannot restore, output path already exists: %s\", opt.OutputPath)\n\t} else if !os.IsNotExist(err) {\n\t\treturn err\n\t}\n\n\t// Find all generations.\n\tgenerations, err := client.GenerationsV3(ctx)","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L1052-L1088","documentation":"RestoreV3 restores from the legacy v0.3.x backup format, which requires the configured replica client to also implement the ReplicaClientV3 interface. This error means the active client (a modern v0.5+ backend) does not implement that interface, so a v0.3.x-format restore cannot be performed against it.","triggerScenarios":"Calling r.RestoreV3(ctx, opt) (or Restore against a legacy-path that selects V3) when the r.Client type assertion `client, ok := r.Client.(ReplicaClientV3)` fails — i.e., the storage backend lacks the V3 interface methods.","commonSituations":"Attempting to restore an old v0.3.x snapshot with a current config pointing at a v0.5+ replica client, using a custom storage backend that only implements the modern ReplicaClient interface, mixing old litestream data directories with new client types.","solutions":["Restore v0.3.x backups using litestream v0.3.x binary instead","Use a client implementation that implements ReplicaClientV3 for the legacy restore path","Migrate the old backup: restore with v0.3.x, then re-replicate with the current litestream version","If you intend a normal restore, call Restore (not RestoreV3) against the modern client"],"exampleFix":"// before\nif err := r.RestoreV3(ctx, opt); err != nil { ... } // client lacks ReplicaClientV3\n// after: normal restore on the modern client\nif err := r.Restore(ctx, opt); err != nil { ... }","handlingStrategy":"type-guard","validationCode":"func supportsV3Restore(r *litestream.Replica) bool {\n    _, ok := r.Client.(litestream.ReplicaClientV3)\n    return ok\n}\n\n// before restoring:\nif !supportsV3Restore(replica) {\n    return errors.New(\"v0.3.x restore unavailable with this client; use litestream v0.3.x or a modern restore\")\n}","typeGuard":"func asV3Client(c litestream.ReplicaClient) (litestream.ReplicaClientV3, bool) {\n    v3, ok := c.(litestream.ReplicaClientV3)\n    return v3, ok\n}","tryCatchPattern":"if err := r.RestoreV3(ctx, opt); err != nil {\n    if strings.Contains(err.Error(), \"does not support v0.3.x restore\") {\n        return fmt.Errorf(\"legacy restore unsupported; restore with litestream v0.3.x, then re-replicate: %w\", err)\n    }\n    return err\n}","preventionTips":["Pin the litestream version to the format era of your backups before restoring","Check interface support (type assertion) before invoking version-specific restore paths","Migrate old v0.3.x replicas to the current format early; do not keep legacy backups as the only recovery path","Use the modern Restore path for v0.5+ replicas"],"tags":["restore","compatibility","versioning","v0-3"],"backgroundTag":"unsupported-operation","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}