{"record":{"id":"273ba561726e8eaa","repo":"argoproj/argo-workflows","slug":"failed-to-put-file-w","errorCode":null,"errorMessage":"failed to put file: %w","messagePattern":"failed to put file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/s3/s3.go","lineNumber":358,"sourceCode":"\t\t\tObjectLocking: outputArtifact.S3.CreateBucketIfNotPresent.ObjectLocking,\n\t\t})\n\t\talreadyExists := bucketAlreadyExistsErr(makeBucketErr)\n\t\tlog.WithField(\"bucket\", outputArtifact.S3.Bucket).\n\t\t\tWithField(\"alreadyExists\", alreadyExists).\n\t\t\tWithError(makeBucketErr).\n\t\t\tInfo(ctx, \"create bucket failed\")\n\t\tif makeBucketErr != nil && !alreadyExists {\n\t\t\treturn !isTransientS3Err(ctx, makeBucketErr), fmt.Errorf(\"failed to create bucket %s: %w\", outputArtifact.S3.Bucket, makeBucketErr)\n\t\t}\n\t}\n\n\tif isDir {\n\t\tif err = s3cli.PutDirectory(outputArtifact.S3.Bucket, outputArtifact.S3.Key, path); err != nil {\n\t\t\treturn !isTransientS3Err(ctx, err), fmt.Errorf(\"failed to put directory: %w\", err)\n\t\t}\n\t} else {\n\t\tif err = s3cli.PutFile(outputArtifact.S3.Bucket, outputArtifact.S3.Key, path); err != nil {\n\t\t\treturn !isTransientS3Err(ctx, err), fmt.Errorf(\"failed to put file: %w\", err)\n\t\t}\n\t}\n\treturn true, nil\n}\n\nfunc bucketAlreadyExistsErr(err error) bool {\n\tresp := &minio.ErrorResponse{}\n\t// https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html\n\talreadyExistsCodes := map[string]bool{\"BucketAlreadyExists\": true, \"BucketAlreadyOwnedByYou\": true}\n\treturn errors.As(err, resp) && alreadyExistsCodes[resp.Code]\n}\n\n// ListObjects returns the files inside the directory represented by the Artifact\nfunc (s3Driver *ArtifactDriver) ListObjects(ctx context.Context, artifact *wfv1.Artifact) ([]string, error) {\n\tctx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\tvar files []string","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/s3/s3.go#L340-L376","documentation":"Wraps a failure from the Minio client PutFile call when saving a single-file S3 artifact. Argo's executor retries transient S3 errors (throttling, network blips); when the error is non-transient or retries are exhausted, this wrapper is returned so artifact saving fails the node. The %w wrapping preserves the underlying Minio/S3 error cause.","triggerScenarios":"saveS3Artifact calls s3cli.PutFile and Minio returns an error: wrong bucket/key permissions, missing bucket, nonexistent local path, invalid credentials, or S3 outage beyond the retry backoff.","commonSituations":"IAM/Minio policy denies s3:PutObject; artifact repository bucket misconfigured in workflow-controller-configmap; accessKey/secretKey wrong or rotated; local file deleted before save; endpoint TLS misconfiguration.","solutions":["Check the wrapped underlying error cause for the real S3 failure (permissions, missing bucket, credentials)","Verify s3 bucket/endpoint/keyFormat in the artifact repository config and the artifact's S3 key","Confirm the artifact source path exists in the container and the step actually produced the file","Test credentials with aws s3 cp or mc cp against the same endpoint/bucket"],"exampleFix":"// before\ns3cli.PutFile(bucket, key, path) // fails: bucket missing\n// after\n# create/verify bucket first\naws --endpoint-url $ENDPOINT s3 mb s3://my-bucket","handlingStrategy":"retry","validationCode":"// pre-flight: ensure artifact source exists and bucket is writable\nif _, err := os.Stat(path); err != nil { return fmt.Errorf(\"artifact path missing: %w\", err) }\n_, err := mc.StatObject(ctx, bucket, keyPrefix, minio.StatObjectOptions{})","typeGuard":null,"tryCatchPattern":"// executor already retries transient errors; on workflow failure\nif strings.Contains(err.Error(), \"failed to put file\") {\n  log.Printf(\"S3 put failed, check bucket/creds: %v\", errors.Unwrap(err))\n}","preventionTips":["Verify bucket exists and IAM allows s3:PutObject before submitting workflows","Test artifact credentials with aws s3 cp / mc cp from a pod in the same namespace","Keep output artifacts written before step exit so the path exists at save time","Monitor for Throttling/SlowDown and increase retry backoff"],"tags":["s3","artifacts","storage","network"],"backgroundTag":"s3-artifact-upload-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}