skip to content

In the Go standard library, what does a Deprecated: marker on a function change for callers?

level: middleimportance: nice to knowfreq 26%

answer

  1. a convention, not a compiler feature
  2. the build stays green
  3. the promise forbids the alternative
  4. replacement ships beside the old one
  5. migrate when convenient, no deadline

basics

~20 s

Nothing at build time. A Deprecated: paragraph is a documentation convention: the code still compiles, still runs and still gets security fixes. Under the Go 1 promise it is never removed, and the replacement ships alongside it.

solid answer

~40 s

`Deprecated:` is a convention, not a language feature. A doc-comment paragraph beginning with that word marks an API as no longer recommended; the compiler knows nothing about it, `go build` and `go test` do not fail, and callers keep working. Editors and analysis tools surface it, and that is the entire enforcement mechanism. Because the Go 1 compatibility promise forbids removing documented standard-library API, deprecation is the only tool available: `io/ioutil` still exists as thin wrappers over `os` and `io`, `math/rand.Seed` still exists, and their replacements arrived beside them rather than in place of them. So read a deprecation as "this will never be improved, migrate when convenient", never as "this disappears in two releases".

go deeper

for a junior

Remember that a deprecated standard-library call still compiles and still works. Nothing fails; it is a documentation signal telling you what to prefer in new code.

for a middle

Explain the link to policy: the Go 1 promise forbids removal, so deprecation plus a replacement at a new import path is the only retirement mechanism available.

for a senior

Show your migration posture — opportunistic, tied to files you are already touching, with the reasoning recorded so reviewers do not re-litigate each remaining call site.

for a principal

Decide how the organisation reads deprecation signals: which ones are worth a coordinated migration because the replacement is materially better, and which are noise to leave alone.

## A convention, not a mechanism Go has no deprecation attribute, annotation or pragma. The convention is a paragraph in a doc comment that begins with the word `Deprecated:`, followed by what to use instead. Documentation tooling recognises the paragraph and renders it prominently; editors grey out or strike through the identifier. The compiler does not participate at all: code calling a deprecated function compiles exactly as before, `go build` succeeds, `go vet` does not fail on it, and the produced binary is unchanged. ## Why the standard library needs it The Go 1 compatibility promise forbids removing documented standard-library API. That leaves precisely one route for retiring a design mistake: leave it in place, mark it, and ship the replacement beside it. So the standard library accumulates API nobody should reach for any more: - `io/ioutil` is deprecated as a package; its functions are now thin wrappers over the equivalents in `os` and `io`, and they keep working. - `math/rand.Seed` is deprecated, while `math/rand/v2` (Go 1.22) is a whole new package at a new import path rather than a change to the old one. - `strings.Title` is deprecated because it cannot handle Unicode case rules correctly, but deleting it was never an option. A new import path is the key trick: `math/rand/v2` and `encoding/json/v2` (Go 1.27) are new packages, so existing importers are untouched by their existence. ## What deprecation actually costs you Since nothing breaks, the cost is not a deadline; it is stagnation. Deprecated API is maintained for correctness and security but not developed: it gains no features, gets no performance work, and its replacement is where the improvements land. Depending on it also puts a small tax on every code review, because each reader has to decide whether this call site is the one nobody has migrated yet. The right posture is opportunistic migration. Move a call site when you are already editing the file, keep the replacement in whatever conventions document your team uses, and do not run a big-bang migration project for something that will still compile in five years. ## The misreading to avoid Engineers arriving from ecosystems with deprecate-then-delete cycles read `Deprecated:` as a countdown and plan an urgent migration; others read the absence of a build failure as evidence that nothing is wrong and never migrate. Both are wrong in the same way — they assume the marker carries enforcement. In Go it carries information only, and the promise behind it is what makes that safe.

  • Does anything in the go toolchain fail a build because of a Deprecated: marker?
    No. The compiler treats it as an ordinary comment, and neither `go build` nor `go test` nor `go vet` fails on a deprecated call. Editors and separate analysis tools surface it, which is the whole enforcement story — deliberately, since the promise means the API will keep working indefinitely.
  • Why did Go add math/rand/v2 instead of fixing math/rand in place?
    Because fixing it in place would change documented behaviour and signatures, which the Go 1 promise forbids. A new import path is a new package, so existing callers of `math/rand` are unaffected while new code gets the better API. Go 1.27 used the same route for `encoding/json/v2`.
  • If deprecated standard-library API never disappears, what is the practical cost of leaving it in your codebase?
    It stops improving. Deprecated API is maintained for correctness and security but gains no features or performance work, and the replacement is where everything new lands. There is also a review tax: each reader must decide whether that call site is simply un-migrated. Migrate opportunistically rather than as a project.

saying these in an interview costs you the question

  • Says deprecated standard-library API is deleted a few releases later
  • Expects go build or go vet to fail on a deprecated call
  • Thinks deprecated packages stop getting security fixes
  • Treats Deprecated: as a compiler annotation with enforcement
  • Plans an urgent big-bang migration off a deprecated call