Skip to content

aws-sd provider: parseHostname fails for dotted Cloud Map service names #6364

@am-ltk

Description

@am-ltk

What happened:

The parseHostname function in the aws-sd provider splits hostnames at the first dot with no awareness of actual Cloud Map namespace boundaries. When a Cloud Map service name contains a dot (e.g., my-app.elb in namespace dev.local), the hostname my-app.elb.dev.local is incorrectly parsed as:

  • service: my-app
  • namespace: elb.dev.local

Instead of the correct:

  • service: my-app.elb
  • namespace: dev.local

matchingNamespaces then does an exact-match lookup and finds no namespace named elb.dev.local, so the record is silently dropped with:

Skipping record <hostname> because no namespace matching record DNS Name was detected

No --domain-filter workaround is possible because the issue is in hostname parsing, not namespace filtering.

This same root cause also affects SRV records (see #5714), where hostnames like _backend._tcp.backend.mynet.svc.internal are parsed with namespace _tcp.backend.mynet.svc.internal instead of mynet.svc.internal.

What you expected to happen:

parseHostname should use known Cloud Map namespace boundaries (longest-suffix matching) to correctly split the hostname, so that my-app.elb.dev.local with namespace dev.local yields service my-app.elb.

How to reproduce it (as minimally and precisely as possible):

  1. Create a Cloud Map namespace dev.local (private DNS)
  2. Deploy external-dns with --provider=aws-sd --domain-filter=dev.local
  3. Create a Kubernetes Ingress or Service with hostname something.dotted.dev.local
  4. Observe external-dns logs:
level=warning msg="Skipping record something.dotted.dev.local 0 IN  because no namespace matching record DNS Name was detected"

No Cloud Map service is created. A control test with a non-dotted hostname like simple.dev.local works correctly.

Anything else we need to know?:

The root cause is in provider/awssd/aws_sd.go, function parseHostname (~line 643):

func (p *AWSSDProvider) parseHostname(hostname string) (string, string) {
    parts := strings.Split(hostname, ".")
    return strings.Join(parts[1:], "."), parts[0]
}

This function has been unchanged since the aws-sd provider was created. The fix is to pass known namespaces into parseHostname and use longest-suffix matching, falling back to the original first-dot split for backward compatibility.

Also fixes #5714 (SRV records skipped with aws-sd).

Environment:

  • External-DNS version: v0.15.1 through v0.21.0 (all current releases)
  • DNS provider: aws-sd (AWS Cloud Map)
  • Others: Tested on EKS with external-dns v0.20.0-eksbuild.5

Checklist

  • I have searched existing issues and tried to find a fix myself
  • I am using the latest release, or have checked the staging image to confirm the bug is still reproducible
  • I have provided the actual process flags (not Helm values)
  • I have provided kubectl get <resource> -o yaml output including status
  • I have provided full external-dns debug logs
  • I have described what DNS records exist and what I expected

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions