zitadel/zitadel · error
upload failed: %w
Error message
upload failed: %w
What it means
The actual storage upload (uploader.UploadAsset, which invokes the command layer to persist the asset to S3/GCS/db storage) failed; the handler wraps the underlying storage error as 500 'upload failed'.
Source
Thrown at internal/api/assets/asset.go:200
}
resourceOwner := uploader.ResourceOwner(authz.GetInstance(ctx), ctxData)
objectName, err := uploader.ObjectName(ctxData)
if err != nil {
s.ErrorHandler()(w, r, fmt.Errorf("upload failed: %v", err), http.StatusInternalServerError)
return
}
uploadInfo := &command.AssetUpload{
ResourceOwner: resourceOwner,
ObjectName: objectName,
ContentType: mimeType.String(),
ObjectType: uploader.ObjectType(),
File: file,
Size: size,
}
err = uploader.UploadAsset(ctx, ctxData.OrgID, uploadInfo, s.Commands())
if err != nil {
s.ErrorHandler()(w, r, fmt.Errorf("upload failed: %w", err), http.StatusInternalServerError)
return
}
}
}
func DownloadHandleFunc(s AssetsService, downloader Downloader) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if s.Storage() == nil {
return
}
ctx := r.Context()
ownerPath := mux.Vars(r)["owner"]
resourceOwner := downloader.ResourceOwner(ctx, ownerPath)
path := ""
if ownerPath != "" {
splitPath := strings.Split(r.RequestURI, ownerPath+"/")
if len(splitPath) < 2 {
s.ErrorHandler()(w, r, fmt.Errorf("invalid request URI format: %v", r.RequestURI), http.StatusNotFound)View on GitHub (pinned to 13948f2bcd)
Solutions
- Inspect server logs for the wrapped inner error from UploadAsset
- Verify storage backend config (endpoint, bucket, access keys) and that the bucket exists and is writable
- Test database/storage connectivity and re-upload
Example fix
// before Storage: Type: s3 Endpoint: https://minio.internal:9000 Bucket: zitadel-assets # bucket does not exist // after # create the bucket first, then: Storage: Type: s3 Endpoint: https://minio.internal:9000 Bucket: zitadel-assets AccessKeyID: <key> SecretAccessKey: <secret>
Defensive patterns
Strategy: retry
Validate before calling
// preflight: verify storage backend reachability/credentials before large uploads
await fetch(`${storageHealthEndpoint}`); // or test-list the configured bucket in ops tooling Try / catch
try {
await uploadToOrgAssets(orgId, file);
} catch (e) {
if (e.status === 500 && e.message.includes("upload failed")) {
await backoff(3, () => uploadToOrgAssets(orgId, file)); // safe to retry idempotent uploads
}
} Prevention
- Monitor S3/GCS/db availability; upload failures are usually infrastructure
- Verify bucket credentials and writability after every storage config change
- Keep uploads idempotent so retry after transient storage errors is safe
When it happens
Trigger: UploadAsset returns an error from the storage backend or the event/command layer: bucket missing, credentials invalid, network failure to S3/GCS, or command-side validation (e.g. asset type not allowed for the resource owner).
Common situations: Misconfigured S3 endpoint/keys in the storage config; MinIO not reachable; permission denied writing to the bucket; database connectivity issues during the command commit.
Related errors
- cannot start asset storage client: %w
- upload failed: %v
- invalid content-type: %s
- file too big, max file size is %vKB
- invalid request URI format: %v
AI-assisted analysis of zitadel/zitadel@13948f2bcd (2026-09-06).
Data as JSON: /api/errors/25f58e075bc7d82e.
Report an issue: GitHub.