kopia/kopia · error
ResolvePolicy
Error message
ResolvePolicy
What it means
ResolvePolicy() POSTs to 'policy/resolve?<target params>' to get the effective (merged) policy. Any request failure is wrapped as "ResolvePolicy". It indicates the resolve request failed rather than the policy being undefined.
Solutions
- Confirm server connectivity and that both sides support policy/resolve.
- Check the SourceInfo used for policyTargetURLParameters is valid and properly encoded.
- Unwrap the error for the HTTP status to distinguish 404/405 (endpoint missing) from transport errors.
- Retry after transient connectivity failures.
Example fix
// before
res, err := serverapi.ResolvePolicy(ctx, cli, si, req)
if err != nil { return err }
// after
res, err := serverapi.ResolvePolicy(ctx, cli, si, req)
if err != nil {
return errors.Wrapf(err, "resolving policy for %v", si)
} Defensive patterns
Strategy: try-catch
Validate before calling
if req == nil { return errors.New("nil ResolvePolicyRequest") }
if si.Host == "" { return errors.New("missing host in policy target") } Type guard
func isResolvePolicyErr(err error) bool { return err != nil && strings.Contains(err.Error(), "ResolvePolicy") } Try / catch
resp, err := serverapi.ResolvePolicy(ctx, cli, si, req)
if err != nil {
return nil, errors.Wrapf(err, "resolve policy for %v", si)
} Prevention
- Ensure both client and server support policy/resolve.
- Validate SourceInfo used for URL parameters.
- Retry on transient connectivity errors.
- Log the unwrapped cause to spot 404/405 endpoint-mismatch cases.
When it happens
Trigger: Calling serverapi.ResolvePolicy against an unreachable server, with a ResolvePolicyRequest the server rejects, or malformed target URL parameters from the SourceInfo.
Common situations: Anonymous test callers resolving policies before the server is connected; source paths with characters that break the query string; server without the policy/resolve endpoint (version mismatch).
Related errors
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/bb6ca7f5a22a8ffc.
Report an issue: GitHub.
Appendix: source
Thrown at internal/serverapi/client_wrappers.go:196
return fmt.Sprintf("userName=%v&host=%v&path=%v", si.UserName, si.Host, si.Path)
}
// SetPolicy sets the policy.
func SetPolicy(ctx context.Context, c *apiclient.KopiaAPIClient, si snapshot.SourceInfo, pol *policy.Policy) error {
resp := &Empty{}
if err := c.Put(ctx, "policy?"+policyTargetURLParameters(si), pol, resp); err != nil {
return errors.Wrap(err, "SetPolicy")
}
return nil
}
// ResolvePolicy resolves the policy.
func ResolvePolicy(ctx context.Context, c *apiclient.KopiaAPIClient, si snapshot.SourceInfo, req *ResolvePolicyRequest) (*ResolvePolicyResponse, error) {
resp := &ResolvePolicyResponse{}
if err := c.Post(ctx, "policy/resolve?"+policyTargetURLParameters(si), req, resp); err != nil {
return nil, errors.Wrap(err, "ResolvePolicy")
}
return resp, nil
}
// ListTasks lists the tasks.
func ListTasks(ctx context.Context, c *apiclient.KopiaAPIClient) (*TaskListResponse, error) {
resp := &TaskListResponse{}
if err := c.Get(ctx, "tasks", nil, resp); err != nil {
return nil, errors.Wrap(err, "ListTasks")
}
return resp, nil
}
// GetObject returns the object payload.
func GetObject(ctx context.Context, c *apiclient.KopiaAPIClient, objectID string) ([]byte, error) {
var b []byteView on GitHub (pinned to 82495e54b5)