crowdsecurity/crowdsec · error
cloudwatch path must contain group and stream : /my/group/na
Error message
cloudwatch path must contain group and stream : /my/group/name:stream/name
What it means
After the query split, the path portion must be exactly 'group:stream' — a single ':' separating the log group from the stream name. A path with zero or multiple ':' cannot identify both group and stream, so ConfigureByDSN returns this error.
Source
Thrown at pkg/acquisition/modules/cloudwatch/config.go:212
s.logger.Infof("Adding cloudwatch group '%s' (stream:%s) to datasources", s.Config.GroupName, targetStream)
return nil
}
func (s *Source) ConfigureByDSN(ctx context.Context, dsn string, labels map[string]string, logger *log.Entry, uuid string) error {
s.logger = logger
dsn = strings.TrimPrefix(dsn, s.GetName()+"://")
args := strings.Split(dsn, "?")
if len(args) != 2 {
return errors.New("query is mandatory (at least start_date and end_date or backlog)")
}
frags := strings.Split(args[0], ":")
if len(frags) != 2 {
return errors.New("cloudwatch path must contain group and stream : /my/group/name:stream/name")
}
s.Config.GroupName = frags[0]
s.Config.StreamName = &frags[1]
s.Config.Labels = labels
s.Config.UniqueId = uuid
u, err := url.ParseQuery(args[1])
if err != nil {
return fmt.Errorf("while parsing %s: %w", dsn, err)
}
for k, v := range u {
switch k {
case "log_level":
if len(v) != 1 {
return errors.New("expected zero or one value for 'log_level'")
}View on GitHub (pinned to 909b515798)
Solutions
- Format the DSN path as /<group-name>:<stream-name> with exactly one colon
- URL-encode any ':' inside group/stream names instead of leaving it literal
- Verify against the CloudWatch console that the group and stream names are correct
Example fix
// before cloudwatch:///my/log/group?backlog=1h // after cloudwatch:///my/log/group:my-stream?backlog=1h
Defensive patterns
Strategy: validation
Validate before calling
path := strings.SplitN(strings.TrimPrefix(dsn, "cloudwatch://"), "?", 2)[0]
if len(strings.Split(path, ":")) != 2 { return errors.New("DSN path must be /group:stream") } Type guard
func cwPathOk(dsn string) bool {
p := strings.SplitN(strings.TrimPrefix(dsn, "cloudwatch://"), "?", 2)[0]
return len(strings.Split(p, ":")) == 2
} Try / catch
if err := src.ConfigureByDSN(dsn, logger, labels, uuid); err != nil {
if strings.Contains(err.Error(), "path must contain group and stream") { /* fix /group:stream */ }
return err
} Prevention
- Always format the DSN path as /<group>:<stream>
- URL-encode colons inside group/stream names
- Test the DSN with cscli or a dry run before deploying
When it happens
Trigger: ConfigureByDSN receives a DSN whose path (before '?') splits on ':' into != 2 fragments, e.g. cloudwatch:///mygroup?backlog=1h (no stream) or cloudwatch:///a:b:c?backlog=1h (extra colon).
Common situations: Forgetting the ':stream' part of the DSN; using a stream name or group containing a literal ':'; typos when hand-editing DSN strings in acquisition.yaml.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- query is mandatory (at least start_date and end_date or back
- while parsing %s: %w
- group_name is mandatory for CloudwatchSource
- aws_region is not specified, specify it or aws_config_dir
- empty loki host
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/5fa0b2de35f53c24.
Report an issue: GitHub.