Why can `go doc ./pkg` and a package's pkg.go.dev page show different documentation?
answer
- one reads disk, the other reads a published version
- no network on one side, a proxy on the other
- the page defaults to the latest release
- unexported names are local-only
- a private module has no public page
basics
~20 sgo doc reads source on your machine, so it shows your working tree as it is now. pkg.go.dev renders a published module version fetched through the public proxy, so it lags your code and never shows a private module.
solid answer
~50 sThey read different sources. `go doc` is a local command over the source in your working tree or module cache: it needs no network, it shows the code exactly as it is right now including uncommitted edits, and `-u` will even show unexported symbols. The public site renders a **published module version** obtained through the module proxy, so it shows whichever version the reader selected — by default the latest release — which is why a signature you changed weeks ago can still be on the page: the change is on your default branch and was never tagged, or the reader is pinned to an older version. The site also renders things `go doc` never prints — rendered links, runnable examples, the version list, imports and importers, licence — and it will never show a module that only resolves through a private host.
code
text · 5 linesgo doc ./pkg # package comment + one-line exported declarations
go doc -all ./pkg # every exported symbol with its full doc comment
go doc -u ./pkg parseRow # include an unexported symbol
go doc -src ./pkg Fetch # print the source of one symbol
go doc net/http.Client # a standard library type, read locallygo deeper
Know the basic split: go doc is a command that reads source on your machine and prints text, while the public site is a website rendering module versions that were published.
Explain the default output of go doc versus -all and -u, and why the site cannot show unexported names, uncommitted work, or a module that never reached the public proxy.
Diagnose a stale-documentation report methodically — which version the reader saw, whether the change was published, whether the prose itself drifted — and audit a package's rendered documentation as part of releasing it.
Decide whether your team treats the published page as an interface it owns, which makes doc-only releases legitimate, and what internal packages point at instead when no public page will ever exist.
## Two different readers of the same comments The doc comments in your source feed two consumers, and confusing them is the usual cause of a documentation complaint that nobody can reproduce. **`go doc` is a local command.** It parses source it can already reach: the package in your working tree, or a dependency in the local module cache. There is no network step and no publishing step. It therefore shows **your code as it is on disk right now** — including edits you have not committed. Its output is plain text. - `go doc ./pkg` prints the package comment plus one-line declarations of the exported symbols — an index, not the full prose. - `go doc -all ./pkg` prints every exported symbol with its complete doc comment. - `go doc ./pkg Fetch` prints one symbol; `go doc net/http.Client` reaches into the standard library the same way. - `go doc -u` includes unexported identifiers, `-src` prints the source of the symbol, `-short` gives a one-line form per symbol, and `-cmd` shows a main package's exported symbols as if it were an ordinary package. **The public documentation site renders published module versions.** It works from what the module proxy serves, which means a version has to exist and be fetchable before the site can show it. The page is HTML: doc links become real links, headings become a table of contents, example functions become expandable runnable blocks, and the page carries material that never came from a doc comment at all — the list of versions, the imports and importers, the licence, the module's README. ## Why the page says something your code does not Work through the usual causes in order: 1. **Which version is the reader looking at?** The page defaults to the latest release of the module, not your default branch. If you changed a signature and did not publish a new version, the page is correct about the version it is showing and stale about your work. 2. **Is the reader pinned?** A page for an older version stays available forever, and a link shared months ago points at that version. 3. **Is it exported?** The site never shows unexported identifiers. A comment you can read locally with `-u` will never appear publicly. 4. **Is the module public at all?** A module whose path resolves only through a private host never reaches the public proxy, so it has no page. Locally, `go doc` is unaffected, which is exactly why teams with private modules must build the habit of reading documentation with the command instead of the site. 5. **Is the prose itself stale?** Nothing checks comments against code. A doc comment describing the constructor from two releases ago renders faithfully and wrongly on both. ## Reading them side by side The practical technique before a release is to open both. Run `go doc -all ./pkg` on the branch you are about to publish and read it as a stranger would read the page: does the package comment orient someone, does every exported symbol have prose, does any first sentence read as an orphan. Then open the currently published version's page and diff what changed in the reader's experience, not just in the source. That catches the two failures the source diff hides — documentation that is missing for a newly exported symbol, and documentation that is present but describes the older behaviour. ## Consequences for how a team publishes The asymmetry has an operational shape. Because the public page tracks published versions, **documentation ships when a version ships**: a fix to a misleading paragraph is not live for readers until you cut a release, and there is no way to edit the page for an already-published version. Teams that care about the page therefore treat a doc-only change as a legitimate reason to publish, and treat the release checklist as including a read of the rendered documentation. For internal packages the same discipline applies to a different artefact: the command output, which is always current, becomes the canonical answer, and internal instructions should point at it rather than at a site that will never have the module.
- A colleague says the site shows a signature you changed weeks ago. What do you check first?Which version the page is displaying — it defaults to the latest published release, and a shared link can be pinned to an older one. If your change is only on the default branch and was never released, the page is right about that version. Confirm locally with `go doc -all` on your branch, then publish a version if the fix needs to be visible.
- How do people read documentation for a package in a private module?Locally, with `go doc`, against the module in their working tree or module cache. A module path that resolves only through a private host never reaches the public proxy, so no page exists and none ever will. Teams in that situation should point their onboarding at the command, since it is always current and needs no publishing step.
- Which go doc invocations are worth running before a release?`go doc ./pkg` to see the index a reader meets first, then `go doc -all ./pkg` to read every exported symbol's prose in one pass — that is where a newly exported name with no comment stands out. `-u` shows unexported identifiers when you are reviewing internal prose, and `-src` prints a symbol's source when you suspect the comment and the code have drifted.
- Why does a doc-only fix sometimes justify publishing a new module version?Because the public page is generated from published versions, there is no way to correct the page for a version already out. A paragraph that misleads callers stays live until a new version exists. Teams that treat their page as an interface therefore accept doc-only releases rather than leaving a wrong instruction visible for a whole release cycle.
saying these in an interview costs you the question
- Assumes the public page rebuilds from the default branch on every push
- Thinks go doc needs network access to work
- Expects unexported identifiers to appear on the public page
- Believes a private module will still get a public page
- Forgets the page defaults to the latest published version, not main
- Trusts the source diff instead of reading the rendered documentation