Skip to content

math/rand: make global Seed a no-op #67273

Closed

Description

@rsc

In Go 1.24, I propose to make rand.Seed (the top-level function) a no-op, controlled by GODEBUG=randseednop=1. (Because it is GODEBUG-controlled, specific programs could opt back to the old behavior using a //go:debug line, through Go 1.27 at least.)

The rationale is that rand.Seed is already deprecated, but it is preventing math/rand users from getting more secure randomness by default. There exist imported packages that call rand.Seed(time.Now().UnixNano()) “just in case”, and that makes math/rand fall back to the old Go 1 generator.

There no doubt exist some programs that use rand.Seed correctly for a reproducible simulation or the like, with only one goroutine at a time using the randomness, and being careful not to call any standard library or other packages that themselves contain even a single call to rand.Int or any other top-level function. It is possible, but it is fragile. (This is the same argument we made to auto-seed and deprecate Seed in the first place.)

Those programs can do what we said back then: instead of rand.Seed(s), use r := rand.New(rand.NewSource(s)) and pass r around. They can even name the variable rand to minimize code updates. They can even:

import mathrand "math/rand"
var rand = mathrand.New(mathrand.NewSource(seed))

Making those already-fragile programs convert to this form will remove the fragility, and it will let us fix the majority case of programs that don't care about reproducibility but are getting the insecure Go 1 generator when they could instead be getting the secure ChaCha8 generator.

If Go 1.28 retired the GODEBUG (following our “minimum four release” policy for GODEBUGs), then at that point we could make math/rand's top-level functions trivial wrappers around math/rand/v2's top-level functions, making them eligible for gofix to update. (Note that Go 1.28 would not arrive until the year 2027 - this is very much playing the long game.)

Activity

  1. added this to the Proposal milestone on May 9, 2024
  2. moved this to Incoming in Proposalson May 9, 2024
  3. apparentlymart commented on May 9, 2024

    @apparentlymart

    I am tangentially responsible for a codebase that does use fixed seeding to produce reproducible random numbers, and so I was initially concerned by this proposal, but I see that it's talking specifically about the global rand.Seed and would not affect the ability to instantiate a source with a specified seed.

    That seems very reasonable to me. Expecting the shared global source to have a predictable seed, even though literally anything in the program could reseed it at any time, seems like an unreasonable expectation.


    The current docs for rand.Seed promise that one can call rand.Seed(1) to achieve behavior from older versions of Go. Would that promise somehow be kept, e.g. by treating the argument 1 differently than other values? Or do you think it's defensible to break that contract? (I don't have any strong opinion either way)

    Prior to Go 1.20, the generator was seeded like Seed(1) at program startup. To force the old behavior, call Seed(1) at program startup. Alternately, set GODEBUG=randautoseed=0 in the environment before making any calls to functions in this package.

  4. changed the title [-]proposal: math/rand: make Seed a no-op[/-] [+]proposal: math/rand: make global Seed a no-op[/+] on May 9, 2024
  5. rsc commented on May 9, 2024

    @rsc
    ContributorAuthor

    I am tangentially responsible for a codebase that does use fixed seeding to produce reproducible random numbers, and so I was initially concerned by this proposal, but I see that it's talking specifically about the global rand.Seed and would not affect the ability to instantiate a source with a specified seed.

    Indeed. I added "global" to the title. Thanks for pointing out the potential confusion.

    The current docs for rand.Seed promise that one can call rand.Seed(1) to achieve behavior from older versions of Go. Would that promise somehow be kept, e.g. by treating the argument 1 differently than other values? Or do you think it's defensible to break that contract? (I don't have any strong opinion either way)

    No, the promise would be broken, just with a 2+ year grace period. We already broke the promise for what happens when you don't seed, so it's the same promise, broken twice.

  6. rsc commented on May 15, 2024

    @rsc
    ContributorAuthor

    This proposal has been added to the active column of the proposals project
    and will now be reviewed at the weekly proposal review meetings.
    — rsc for the proposal review group

  7. moved this from Incoming to Active in Proposalson May 15, 2024
  8. rsc commented on May 30, 2024

    @rsc
    ContributorAuthor

    Have all remaining concerns about this proposal been addressed?

    The proposal details are in #67273 (comment).

  9. rsc commented on Jun 5, 2024

    @rsc
    ContributorAuthor

    Based on the discussion above, this proposal seems like a likely accept.
    — rsc for the proposal review group

    The proposal details are in #67273 (comment).

  10. moved this from Active to Likely Accept in Proposalson Jun 5, 2024
  11. rsc commented on Jun 12, 2024

    @rsc
    ContributorAuthor

    No change in consensus, so accepted. 🎉
    This issue now tracks the work of implementing the proposal.
    — rsc for the proposal review group

    The proposal details are in #67273 (comment).

  12. moved this from Likely Accept to Accepted in Proposalson Jun 12, 2024
  13. changed the title [-]proposal: math/rand: make global Seed a no-op[/-] [+]math/rand: make global Seed a no-op[/+] on Jun 12, 2024
  14. modified the milestones: Proposal, Backlog on Jun 12, 2024
  15. gopherbot commented on Aug 15, 2024

    @gopherbot
    Contributor

    Change https://go.dev/cl/606055 mentions this issue: math/rand: make calls to Seed no-op

  16. added a commit that references this issue on Aug 19, 2024
    d2b6bdb
  17. gopherbot commented on Aug 14, 2025

    @gopherbot
    Contributor

    Change https://go.dev/cl/696135 mentions this issue: arm64/arm64asm: stop relying on global rand.Seed

  18. modified the milestones: Backlog, Go1.24 on Aug 14, 2025
  19. locked and limited conversation to collaborators on Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions