kopia/kopia · error
unexpected error
Error message
unexpected error
What it means
ValidateProvider's capacity check wraps any unexpected GetCapacity error with the generic message 'unexpected error'. It is used when the storage implementation returns an error other than the tolerated blob.ErrNotAVolume while reporting volume capacity.
Solutions
- Inspect the wrapped cause — it contains the actual GetCapacity failure from the provider.
- Verify credentials have permission for account/capacity metadata APIs.
- Retry after transient network issues resolve.
- If the backend genuinely lacks capacity support, make its GetCapacity return blob.ErrNotAVolume instead of a generic error.
Example fix
// before
return blob.Capacity{}, errors.New("not implemented")
// after
return blob.Capacity{}, blob.ErrNotAVolume Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := st.GetCapacity(ctx); err != nil && !errors.Is(err, blob.ErrNotAVolume) {
return fmt.Errorf("capacity API unavailable: %w", err)
} Type guard
func isNotAVolume(err error) bool {
return errors.Is(err, blob.ErrNotAVolume)
} Try / catch
if err := providervalidation.ValidateProvider(ctx, st, opts); err != nil {
var capErr = strings.Contains(err.Error(), "unexpected error")
if capErr && isAuthErr(errors.Unwrap(err)) {
refreshCredentials(); return retry()
}
return err
} Prevention
- Ensure credentials permit the provider's account/capacity metadata API
- Return blob.ErrNotAVolume from GetCapacity when unsupported, never a generic error
- Refresh credentials before long validation runs
- Retry transient network failures during validation
When it happens
Trigger: st.pickOne().GetCapacity(ctx) fails with a real error (auth failure, network timeout, throttling, API error) rather than returning a Capacity or blob.ErrNotAVolume.
Common situations: Expired storage credentials hitting the provider's capacity/statistics API; Azure requests rejected due to missing permission to query account metadata; transient network failure during validation.
Related errors
- expected volume's free space (%dB) to be at most volume…
- encountered errors
- error listing blobs
- invalid length , expected
- invalid offset
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/f524c916b5c5432e.
Report an issue: GitHub.
Appendix: source
Thrown at internal/providervalidation/providervalidation.go:137
}()
uberPrefix := blob.ID("z" + uuid.NewString())
defer cleanupAllBlobs(ctx, st[0], uberPrefix)
prefix1 := uberPrefix + "a"
prefix2 := uberPrefix + "b"
log(ctx).Info("Validating storage capacity and usage")
c, err := st.pickOne().GetCapacity(ctx)
switch {
case errors.Is(err, blob.ErrNotAVolume):
// This is okay. We expect some implementations to not support this method.
case c.FreeB > c.SizeB:
return errors.Errorf("expected volume's free space (%dB) to be at most volume size (%dB)", c.FreeB, c.SizeB)
case err != nil:
return errors.Wrapf(err, "unexpected error")
}
log(ctx).Info("Validating blob list responses")
if err := verifyBlobCount(ctx, st.pickOne(), uberPrefix, 0); err != nil {
return errors.Wrap(err, "invalid blob count")
}
log(ctx).Info("Validating non-existent blob responses")
var out gather.WriteBuffer
defer out.Close()
// read non-existent full blob
if err := st.pickOne().GetBlob(ctx, prefix1+"1", 0, -1, &out); !errors.Is(err, blob.ErrBlobNotFound) {
return errors.Errorf("got unexpected error when reading non-existent blob: %v", err)
}
View on GitHub (pinned to 82495e54b5)