Fixing Broken pkg and Ports Builds on FreeBSD
How to isolate FreeBSD repository, ABI, lock, dependency, options, distfile, and ports-build failures without damaging package state.
pkg install consumes signed binary repositories; a port build compiles a recipe from a specific Ports Collection revision. They share the installed package database but fail for different reasons. First decide whether the error occurs while selecting a repository, solving package dependencies, downloading an archive, validating installed files, fetching port distfiles, configuring, compiling, staging, or packaging. “pkg/ports is broken” discards the most useful boundary.
Preserve versions, ABI, repositories, and the exact error
Capture system and package-manager identity before forcing updates:
freebsd-version -kru
pkg -vv
pkg repositories
pkg stats
pkg lock -l
pkg -vv exposes the ABI and configuration; pkg repositories shows enabled repository definitions on current pkg versions; locks explain why a solver refuses to replace a dependency. Redact credentials or private repository URLs before sharing output.
Run the failed command again with its complete output preserved. For a package installation, pkg install -n package previews the proposed transaction without applying it. Read the first repository, signature, ABI, conflict, or solver message—not only the final “failed” line.
A catalogue refresh is appropriate when metadata is stale:
pkg update
pkg install and pkg upgrade normally update catalogues automatically unless REPO_AUTOUPDATE is disabled. pkg update -f forces a full redownload and is useful for a suspected corrupt local catalogue, but repeatedly forcing it will not fix DNS, TLS time errors, a disabled repository, wrong ABI, proxy failure, or missing package in the selected branch.
Check repository branch and package availability
FreeBSD’s official package repositories commonly offer quarterly and latest-style branches. A package or version visible on a web portal may not exist in the branch, architecture, or FreeBSD major version configured on the host. Query the active repositories:
pkg search -x '^package-name$'
pkg rquery '%n-%v %R' package-name
Repository configuration files live under the paths documented by pkg-repositories(8). Do not edit /etc/pkg/FreeBSD.conf directly when the documented override directory is appropriate, and do not disable signature verification to make a fetch succeed. A signature failure is a security boundary, not catalogue inconvenience.
After a major FreeBSD upgrade, packages built for the old ABI may need a supported reinstall/upgrade path. Confirm running kernel and userland versions agree before rebuilding third-party software. A host midway through a base upgrade can present an ABI no repository is intended to support.
Audit the installed package database without random reinstalls
Use targeted consistency checks:
pkg check -d
pkg check -s package-name
pkg info package-name
pkg which /usr/local/bin/suspect-command
pkg check -d checks registered dependencies; pkg check -s verifies installed file checksums where recorded. A missing shared library may result from an interrupted transaction, a locally copied file, or mixing repository generations. Capture the exact consumer and provider before forcing every package to reinstall.
Review /usr/local/etc/pkg.conf and repository overrides for local changes. Check held packages deliberately. Unlocking a critical database or language runtime merely to satisfy a solver can trigger a large, incompatible upgrade; understand the planned transaction first.
pkg audit -F checks known vulnerabilities and should be part of normal operations, but it does not validate build correctness or repair dependencies.
Keep the Ports tree aligned with the package strategy
The supported modern way to obtain the Ports Collection is Git. portsnap is historical and is absent from newer FreeBSD base systems. Before updating an existing tree, inspect it:
git -C /usr/ports status --short --branch
git -C /usr/ports remote -v
git -C /usr/ports log -1 --oneline
Preserve local patches and untracked files. If the tree is clean and tracks the intended branch, a fast-forward-only pull avoids an accidental merge:
git -C /usr/ports pull --ff-only
Do not combine packages from a quarterly repository with a ports main tree casually. The Handbook warns that dependencies can differ between HEAD/main and quarterly branches, producing conflicts with packages already installed by pkg. Use one coherent branch and preferably build the complete required package set in a controlled repository.
Reproduce the port failure without installing it
Work from the port origin and separate phases:
cd /usr/ports/www/example
make showconfig
make clean
make fetch
make checksum
make build 2>&1 | tee /tmp/example-build.log
Replace the origin. make build avoids changing the live package database while diagnosing compilation. Inspect the earliest causal compiler/configure message with surrounding context; strings such as *** Error code 1 are make’s propagation, not necessarily the root cause.
Record make -V PKGNAME, make -V MAINTAINER, options, /etc/make.conf, architecture, FreeBSD version, and the Ports commit. Custom compiler flags, DEFAULT_VERSIONS, and stale environment variables are frequent local causes. Reproduce with local overrides removed in a controlled environment before reporting the port broken.
For option mismatches, compare make showconfig with pkg info for installed dependencies. make config-recursive changes stored options throughout a dependency tree and can create a build set different from official packages; it should be a deliberate policy, not a generic repair command.
Handle distfiles and build directories through framework targets
If make checksum fails, preserve the URL and observed checksum. A proxy, captive portal, truncated download, upstream reroll, or stale distinfo can all produce the symptom. Use framework targets such as make distclean, then refetch and verify, instead of deleting wildcard paths that might remove unrelated shared distfiles.
Never “fix” a checksum mismatch by running make makesum as an end user. That rewrites the expected integrity metadata to trust whatever was downloaded. makesum belongs to a port maintainer updating a recipe after verifying upstream artifacts.
Stale work directories can preserve configure results across option or dependency changes. make clean removes the port’s work area; it does not update the recipe or installed dependencies. If a clean build still fails, compare with official package-builder logs and search the FreeBSD Bugzilla database for the origin and exact error.
Prefer poudriere for repeatable source builds
Building directly on a production host lets undeclared dependencies from /usr/local leak into compilation and can replace libraries used by running services. poudriere builds packages in clean jails from a pinned FreeBSD version, architecture, Ports tree, and options set. It produces logs and a repository that pkg can consume as one coherent transaction.
That clean environment distinguishes a real port defect from host contamination. If poudriere succeeds while an in-place build fails, compare environment and installed dependencies. If it fails reproducibly, attach the complete log, Ports revision, jail version, options, and maintainer output to a Problem Report or maintainer request.
Close with a transactional verification
Before applying a repaired package plan, preview it and confirm no unexpected runtime, database, or unrelated service is removed. After installation, run pkg check -d, verify the application’s own version and configuration test, and restart only services whose libraries or binaries changed according to the upgrade guidance.
The reliable sequence is: identify the failing phase, verify repository/ABI/branch, audit installed metadata, reproduce a port cleanly, and only then modify state. Forced catalogues, checksum rewrites, recursive options, and blanket reinstalls can hide evidence; a pinned clean package build turns the same incident into something reproducible and supportable.
Related:
- The FreeBSD Ports Collection vs. pkg: Choosing (and Combining) the Right Tool
- How to Build and Host a Custom pkg Repository
Sources: