{"record":{"id":"b6938063b577f630","repo":"crowdsecurity/crowdsec","slug":"event-s-is-not-supported","errorCode":null,"errorMessage":"event %s is not supported","messagePattern":"event (.+?) is not supported","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/acquisition/modules/s3/run.go","lineNumber":204,"sourceCode":"\t\treturn eventBody.Detail.Bucket.Name, eventBody.Detail.Object.Key, nil\n\t}\n\n\treturn \"\", \"\", errors.New(\"invalid event body for event bridge format\")\n}\n\nfunc extractBucketAndPrefixFromS3Notif(message *string) (string, string, error) {\n\ts3notifBody := events.S3Event{}\n\n\tif err := json.Unmarshal([]byte(*message), &s3notifBody); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tif len(s3notifBody.Records) == 0 {\n\t\treturn \"\", \"\", errors.New(\"no records found in S3 notification\")\n\t}\n\n\tif !strings.HasPrefix(s3notifBody.Records[0].EventName, \"ObjectCreated:\") {\n\t\treturn \"\", \"\", fmt.Errorf(\"event %s is not supported\", s3notifBody.Records[0].EventName)\n\t}\n\n\treturn s3notifBody.Records[0].S3.Bucket.Name, s3notifBody.Records[0].S3.Object.Key, nil\n}\n\nfunc extractBucketAndPrefixFromSNSNotif(message *string) (string, string, error) {\n\tsnsBody := SNSEvent{}\n\n\tif err := json.Unmarshal([]byte(*message), &snsBody); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\t// It's just a SQS message wrapped in SNS\n\treturn extractBucketAndPrefixFromS3Notif(&snsBody.Message)\n}\n\nfunc (s *Source) extractBucketAndPrefix(message *string) (string, string, error) {\n\tswitch s.Config.SQSFormat {","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/s3/run.go#L186-L222","documentation":"extractBucketAndPrefixFromS3Notif parses S3 event notification payloads. Only ObjectCreated:* events are supported; any other EventName in the first record is rejected. This propagates up through SNS notifications and direct S3 notification handling.","triggerScenarios":"An S3 notification (direct or via SNS) whose Records[0].EventName is e.g. ObjectRemoved:Delete, LifecycleExpiration, or Replication events is fed to the source.","commonSituations":"Pointing the S3 source at a queue/topic that also receives ObjectRemoved deletion markers or lifecycle events; testing notifications of the wrong type; versioning enabled so delete events flow in.","solutions":["Configure the S3 bucket notification (or SNS subscription filter) to deliver only ObjectCreated:* events, e.g. filter suffix/prefix and event type s3:ObjectCreated:*.","Ignore or route ObjectRemoved/lifecycle events to a different consumer.","If deletion tracking is needed, it is unsupported by this source — process those events elsewhere."],"exampleFix":"// before: bucket notification config sends s3:ObjectRemoved:* too\n// after: restrict the notification configuration to\n{\"Events\": [\"s3:ObjectCreated:*\"]}","handlingStrategy":"try-catch","validationCode":"var n struct{ Records []struct{ EventName string } `json:\"Records\"` }\nif json.Unmarshal([]byte(body), &n) == nil && len(n.Records) > 0 && !strings.HasPrefix(n.Records[0].EventName, \"ObjectCreated:\") {\n    return fmt.Errorf(\"skipping unsupported event %s\", n.Records[0].EventName)\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := extractBucketAndPrefix(body); err != nil {\n    log.Warnf(\"ignoring unsupported S3 notification: %v\", err)\n    return // skip, do not treat as fatal\n}","preventionTips":["Restrict bucket notifications to s3:ObjectCreated:* event types.","Add SNS subscription filter policies for event name prefixes.","Keep delete/lifecycle events on a separate queue/topic."],"tags":["s3","acquisition","notifications","sns"],"backgroundTag":"unsupported-operation","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}