gravitational/teleport · error

PIV is unavailable in current build

Error message

PIV is unavailable in current build

What it means

In builds compiled without PIV/CGO support (no native YubiKey PIV library linked), NewYubiKeyService returns an unavailableYubiKeyPIVService stub whose every operation (NewPrivateKey, Sign) fails with errPIVUnavailable. It signals that hardware-key PIV functionality is not present in this binary, not that the YubiKey itself is broken.

Source

Thrown at api/utils/keys/piv/service_unavailable.go:30

// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package piv

import (
	"context"
	"crypto"
	"errors"
	"io"

	"github.com/gravitational/trace"

	"github.com/gravitational/teleport/api/utils/keys/hardwarekey"
)

var errPIVUnavailable = errors.New("PIV is unavailable in current build")

func NewYubiKeyService(_ hardwarekey.Prompt) *unavailableYubiKeyPIVService {
	return &unavailableYubiKeyPIVService{}
}

type unavailableYubiKeyPIVService struct{}

func (s *unavailableYubiKeyPIVService) NewPrivateKey(_ context.Context, _ hardwarekey.PrivateKeyConfig) (*hardwarekey.Signer, error) {
	return nil, trace.Wrap(errPIVUnavailable)
}

// Sign performs a cryptographic signature using the specified hardware
// private key and provided signature parameters.
func (s *unavailableYubiKeyPIVService) Sign(_ context.Context, _ *hardwarekey.PrivateKeyRef, _ hardwarekey.ContextualKeyInfo, _ io.Reader, _ []byte, _ crypto.SignerOpts) ([]byte, error) {
	return nil, trace.Wrap(errPIVUnavailable)
}

func (s *unavailableYubiKeyPIVService) SetPrompt(_ hardwarekey.Prompt) {}

View on GitHub (pinned to 1283425b60)

Solutions

  1. Rebuild/install the Teleport binary with CGO and PIV support (the appropriate build tag, e.g. `piv`, with CGO_ENABLED=1).
  2. If hardware keys are not required, avoid the PIV code path or configure the client to use software keys instead.
  3. Check `tsh version`/build flavor to confirm PIV support is compiled in before prompting users for YubiKey operations.

Example fix

// before
go build -tags piv ./tool/tsh // CGO disabled so PIV stub is used

// after
CGO_ENABLED=1 go build -tags piv ./tool/tsh
Defensive patterns

Strategy: fallback

Validate before calling

if !piv.Available() { return errors.New("this binary lacks YubiKey PIV support; use a cgo/piv build") }

Type guard

_, ok := svc.(*piv.YubiKeyPIVService); if !ok { /* stub: PIV unavailable */ }

Try / catch

signer, err := svc.NewPrivateKey(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "PIV is unavailable") {
    return fmt.Errorf("PIV support missing in this build; rebuild with CGO and the piv tag: %w", err)
}

Prevention

When it happens

Trigger: Calling piv.NewPrivateKey to generate/store a private key on a YubiKey, or piv.Sign to sign with one, while running a Teleport binary built without the PIV build tag / CGO (e.g. pure-Go release builds, Windows/Linux non-cgo builds).

Common situations: Using tsh or tbot built without CGO on a machine expecting YubiKey hardware key support; switching from a cgo-enabled build to a lightweight build; container images without libpcsclite/PIV dependencies compiled in.

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/fda908922ad6f3e1. Report an issue: GitHub.