Skip to content

Fake client should retry on GenerateName name collisions #3497

@vieux

Description

@vieux

What happened?

The fake client's Create method generates a single random name when
GenerateName is set and does not retry on collision. If the generated
name matches an existing object in the tracker (including previously
deleted ones that the tracker still retains), it returns AlreadyExists
to the caller.

This causes flaky tests when many objects are created and deleted with
the same GenerateName prefix. With only a 5-character random suffix
(27^5 ≈ 14.3M possibilities), the birthday paradox makes collisions
likely at scale.

What did you expect to happen?

The fake client should match the real Kubernetes API server behavior.
Since Kubernetes 1.32, the RetryGenerateName feature gate is GA and
the API server retries up to 7 times on GenerateName collisions:
kubernetes/kubernetes#115489

The fake client should do the same — retry with a new random suffix
on AlreadyExists when GenerateName was used.

Relevant code

The current single-attempt logic is in pkg/client/fake/client.go
in the Create method:

https://github.com/kubernetes-sigs/controller-runtime/blob/main/pkg/client/fake/client.go#L877-L882

The real API server's retry implementation is in:
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go
(search for generateName / retryCount)

Proposed fix

Wrap the name generation + tracker.Create call in a retry loop
(up to 7 attempts, matching the real API server). On AlreadyExists,
regenerate the random suffix and retry. Only retry when GenerateName
is set — explicit Name collisions should still return an error
immediately.

I'm happy to submit a PR for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions