How to Install CUDA on Debian 13, 12 and 11

Debian 13, 12, and 11 expose different CUDA toolkit branches, so the newest package is not automatically the right choice for every GPU or project. Follow a toolkit-only path, confirm compiler and driver compatibility, compile an error-checked sample, and keep updates, removal, repository cleanup, and rollback method-specific.

Last updatedAuthorJoshua JamesRead time14 minGuide typeDebian

CUDA workloads on Debian need three pieces to line up: a supported NVIDIA GPU, a working NVIDIA driver, and a toolkit branch that matches the code you plan to build. If you need to install CUDA on Debian for machine learning, rendering, scientific computing, or the nvcc compiler, start by choosing whether Debian’s packaged toolkit is new enough or whether NVIDIA’s CUDA repository is a better fit.

The right package source depends on more than the newest version number. Check the CUDA branch required by your project, the GPU generation it supports, and whether you already manage the NVIDIA driver separately. Debian’s archive offers an older, conservative toolkit, while NVIDIA’s repository provides newer and versioned branches.

Install CUDA on Debian

Use the method that matches your toolkit, driver, and hardware requirements. Debian’s repository is simpler when its packaged CUDA branch is sufficient. NVIDIA’s repository is the practical choice when a project needs a newer or explicitly versioned toolkit.

Choose a CUDA Installation Method on Debian

MethodPackage SourceValidated BranchBest FitUpdate Path
Debian repository packagesDebian non-free package archiveDebian 13: CUDA 12.4, Debian 12: CUDA 11.8, Debian 11: CUDA 11.2Systems that prefer Debian-packaged software and can use the archive’s toolkit branchTargeted Debian APT updates
NVIDIA CUDA repositoryNVIDIA CUDA APT repositoryDebian 13 and 12: CUDA 13.3; Debian 11 legacy feed: CUDA 12.6Projects that need a newer or fixed CUDA toolkit branchTargeted NVIDIA repository updates

For most new CUDA development systems with Turing-generation or newer GPUs, start with NVIDIA’s CUDA repository and the toolkit-only package. It tracks current compiler and library releases without installing a driver in that toolkit transaction. The repository still changes APT’s NVIDIA package candidates, so inspect later full-system upgrades if you manage the driver separately. Use Debian’s repository when its toolkit branch meets your project’s requirements or when Debian packaging policy matters more than the newest CUDA features.

Do not choose CUDA 13 only because it is newest. CUDA 13 removed support for Maxwell, Pascal, and Volta in multiple toolkit components, while driver support and individual library requirements can differ. Check your GPU’s compute capability and the CUDA range required by your framework. Older GPUs may need a CUDA 12.x toolkit branch instead.

Hardware boundary: CUDA runtime acceleration requires a compatible NVIDIA GPU and loaded NVIDIA kernel module. A system without a GPU can install the toolkit and compile CUDA source, but nvidia-smi and GPU execution cannot succeed there.

Check Debian Prerequisites for CUDA

Sudo required: If your account cannot use sudo, add it before continuing. The Debian sudo setup is covered in add a user to sudoers on Debian.

Refresh APT metadata before installing packages:

sudo apt update

Install the compiler and PCI inspection tools used for sample compilation and hardware detection:

sudo apt install build-essential pciutils

If this guide will also install or change the NVIDIA driver, install the headers and DKMS tools for the running kernel:

sudo apt install linux-headers-"$(uname -r)" dkms

The toolkit-only commands below can skip that prerequisite. The Debian archive command deliberately uses --no-install-recommends, while NVIDIA’s cuda-toolkit metapackage excludes the kernel driver. If APT installs a newer kernel during maintenance, reboot before changing the driver so the running kernel and installed headers match.

Install CUDA from Debian Repository Packages

This method uses Debian’s nvidia-cuda-toolkit package and can add Debian’s nvidia-driver separately when the system does not already have a suitable driver. It requires Debian’s contrib and non-free components, and Debian 12 or 13 systems should also have non-free-firmware enabled for proprietary firmware packages.

If those components are not already active, use the dedicated walkthrough to enable contrib and non-free repositories on Debian, then refresh APT again:

sudo apt update

Check the toolkit and driver candidates before installing:

apt-cache policy nvidia-cuda-toolkit nvidia-driver

On Debian 13 with the required components enabled, the relevant candidate lines look like this:

nvidia-cuda-toolkit:
  Installed: (none)
  Candidate: 12.4.131~12.4.1-2
nvidia-driver:
  Installed: (none)
  Candidate: 550.163.01-2

Install the Debian-packaged toolkit:

sudo apt install --no-install-recommends nvidia-cuda-toolkit

The --no-install-recommends flag keeps Debian’s recommended DKMS driver, kernel headers, and supporting desktop tools out of a toolkit-only transaction. Required user-space packages such as libcuda1 can still be installed. Omitting the flag can install nvidia-kernel-dkms, build kernel modules, and rebuild the initial ramdisk even though you did not name nvidia-driver.

This path places nvcc in /usr/bin, so a normal shell should find the compiler without adding /usr/local/cuda/bin to your PATH.

If nvidia-smi does not already work and your GPU is supported by Debian’s driver branch, preview the separate driver transaction first:

apt-get -s install nvidia-driver

Review the proposed DKMS, kernel-header, firmware, and driver packages. If they match the supported GPU and driver plan, install them:

sudo apt install nvidia-driver

Reboot only after installing or changing the driver so Debian can load the new kernel module:

sudo reboot

Install CUDA from the NVIDIA Repository

NVIDIA’s current CUDA documentation qualifies Debian 13 and Debian 12 on amd64. NVIDIA still publishes a Debian 11 amd64 feed capped at CUDA 12.6, but Debian 11 is absent from the current CUDA 13 qualification table; treat that feed as a legacy compatibility path and plan an operating-system upgrade.

Add the NVIDIA CUDA Repository

Install the repository tools for this method. The curl command downloads NVIDIA’s repository bootstrap package:

sudo apt install ca-certificates curl

Before changing repository state, list existing CUDA sources. If an older version of this guide created /etc/apt/sources.list.d/nvidia-cuda.sources, confirm that the displayed file points to NVIDIA’s CUDA repository, then remove only that legacy file. Keep any other source until you identify its owner and decide which method should remain active.

grep -R "developer.download.nvidia.com/compute/cuda" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

Only if the output identifies that exact legacy filename, run the guarded removal. It refuses symbolic links, package-owned paths, and files that do not contain NVIDIA’s CUDA repository URL:

LEGACY_CUDA_SOURCE=/etc/apt/sources.list.d/nvidia-cuda.sources
if [ -L "$LEGACY_CUDA_SOURCE" ]; then
  echo "Refusing to remove a symbolic-link source: $LEGACY_CUDA_SOURCE" >&2
elif [ -f "$LEGACY_CUDA_SOURCE" ]; then
  if SOURCE_OWNER="$(dpkg-query -S "$LEGACY_CUDA_SOURCE" 2>&1)"; then
    echo "Refusing to remove package-owned source: $SOURCE_OWNER" >&2
  else
    QUERY_STATUS=$?
    if [ "$QUERY_STATUS" -ne 1 ]; then
      echo "Package ownership query failed: $SOURCE_OWNER" >&2
    elif grep -q "developer.download.nvidia.com/compute/cuda" "$LEGACY_CUDA_SOURCE"; then
      sudo rm -- "$LEGACY_CUDA_SOURCE"
    else
      echo "Refusing to remove a source that does not point to NVIDIA CUDA: $LEGACY_CUDA_SOURCE" >&2
    fi
  fi
fi

Install NVIDIA’s cuda-keyring bootstrap package with release and architecture checks. The package owns the repository source, signing key, and priority pin under APT’s system paths. The subshell stops before downloading anything on an unsupported release or architecture and removes its temporary directory on success or failure.

(
  set -eu
  . /etc/os-release
  ARCH="$(dpkg --print-architecture)"

  case "$VERSION_ID:$ARCH" in
    13:amd64) NVIDIA_DISTRO="debian13" ;;
    12:amd64) NVIDIA_DISTRO="debian12" ;;
    11:amd64) NVIDIA_DISTRO="debian11" ;;
    *) echo "Unsupported Debian release or architecture for this CUDA repository workflow: ${VERSION_ID}:${ARCH}" >&2; exit 1 ;;
  esac

  KEYRING_PACKAGE="cuda-keyring_1.1-1_all.deb"
  TMP_DIR="$(mktemp -d)"
  trap 'rm -rf -- "$TMP_DIR"' EXIT

  curl -fsSLo "$TMP_DIR/$KEYRING_PACKAGE" \
    "https://developer.download.nvidia.com/compute/cuda/repos/${NVIDIA_DISTRO}/x86_64/${KEYRING_PACKAGE}"

  if [ "$(dpkg-deb -f "$TMP_DIR/$KEYRING_PACKAGE" Package)" != "cuda-keyring" ] || \
     [ "$(dpkg-deb -f "$TMP_DIR/$KEYRING_PACKAGE" Version)" != "1.1-1" ] || \
     [ "$(dpkg-deb -f "$TMP_DIR/$KEYRING_PACKAGE" Architecture)" != "all" ]; then
    echo "Unexpected CUDA keyring package metadata." >&2
    exit 1
  fi

  sudo dpkg -i "$TMP_DIR/$KEYRING_PACKAGE"
)

Confirm which source, signing key, and priority pin the package installed before refreshing APT:

dpkg -L cuda-keyring | grep -E '/(sources.list.d|keyrings|preferences.d)/'
grep -R "developer.download.nvidia.com/compute/cuda" /etc/apt/sources.list.d/

Refresh APT metadata and confirm the repository is available:

sudo apt update &&
apt-cache policy cuda cuda-toolkit cuda-drivers nvidia-driver nvidia-open

On Debian 13 and Debian 12 amd64, the candidates validated in July 2026 include:

cuda:
  Installed: (none)
  Candidate: 13.3.1-1
cuda-toolkit:
  Installed: (none)
  Candidate: 13.3.1-1
cuda-drivers:
  Installed: (none)
  Candidate: 610.43.02-1
nvidia-driver:
  Installed: (none)
  Candidate: 610.43.02-1

The cuda-keyring package also installs an APT priority pin for NVIDIA’s repository. Installing cuda-toolkit does not add a driver in that transaction, but the pin can make NVIDIA’s driver packages the preferred candidates during a later broad upgrade. Keep the package-owned pin while using this repository, and simulate full-system upgrades before accepting NVIDIA driver changes.

Install a CUDA Toolkit Package from NVIDIA

Install the toolkit without installing or changing driver packages in this transaction:

sudo apt install cuda-toolkit

On Debian 13 or Debian 12, if the system does not have a working driver and you want NVIDIA’s current toolkit and driver choices together, install the broader cuda metapackage. Current full-stack transactions select NVIDIA’s open kernel modules, which require Turing-generation or newer GPUs. Pre-Turing systems should keep a compatible proprietary driver managed separately and install only the project-compatible toolkit branch. This transaction can install or change driver packages, so simulate it first:

apt-get -s install cuda

Review every proposed driver and DKMS package. Only when that transaction matches the GPU and driver plan, run the real installation:

sudo apt install cuda

On Debian 11, a full cuda transaction also requires Debian’s contrib and non-free components because its driver chain uses packages such as glx-alternative-nvidia. Although that transaction currently resolves, Debian 11 is no longer in NVIDIA’s current qualification table and the feed selects a legacy CUDA 12.6 plus driver stack. Prefer cuda-toolkit-12-6 with a separately validated compatible driver, or upgrade Debian.

For a fixed minor branch, confirm the exact package first, then install the versioned toolkit package. Debian 13 and Debian 12 currently expose cuda-toolkit-13-3, while the legacy Debian 11 feed tops out at cuda-toolkit-12-6:

apt-cache policy cuda-toolkit-13-3 cuda-toolkit-12-6

On Debian 13 or Debian 12, install the current fixed branch with:

sudo apt install cuda-toolkit-13-3

On Debian 11, install the final branch in its legacy feed:

sudo apt install cuda-toolkit-12-6

For a Maxwell, Pascal, or Volta GPU, check the candidate for a project-compatible CUDA 12.x branch instead of installing CUDA 13 by default. Debian 13 readers can use Debian’s CUDA 12.4 package when that older branch meets the project requirements.

If you are looking for CUDA 12.1 on Debian 12, check the candidate before trying old local-installer filenames. NVIDIA’s current Debian 12 network repository does not publish cuda-toolkit-12-1, so use a current branch unless your project specifically requires 12.1 and you are prepared to validate NVIDIA’s archived local installer path separately.

Reboot only if the transaction installed or changed a driver package:

sudo reboot

Verify CUDA on Debian

Verify the package source and compiler separately from the driver. Compiler proof works on a build system without a GPU. Driver and runtime proof require compatible NVIDIA hardware.

Confirm the Installed CUDA Package Source

apt-cache policy cuda-toolkit cuda-toolkit-13-3 cuda-toolkit-12-6 nvidia-cuda-toolkit
dpkg-query -W -f='${binary:Package}\t${Version}\n' \
  cuda-toolkit cuda-toolkit-13-3 cuda-toolkit-12-6 nvidia-cuda-toolkit 2>/dev/null

The installed entries identify the top-level and versioned metapackages selected by your method. The policy output also shows whether each candidate comes from Debian or NVIDIA’s repository.

Check the NVIDIA Driver

First confirm that the machine exposes an NVIDIA PCI device:

lspci -nn | grep -i nvidia

If the command finds no NVIDIA device, skip nvidia-smi and GPU runtime testing on that system. When a device is present, query the loaded driver’s version and then display its full status:

nvidia-smi --query-gpu=name,driver_version --format=csv,noheader
nvidia-smi

A working driver prints the GPU name and driver version. Compare that version with NVIDIA’s CUDA toolkit and driver compatibility tables: CUDA 13.x minor-version compatibility starts at Linux driver 580, while CUDA 13.3 Update 1 corresponds to driver 610.43.02; CUDA 12.x minor compatibility starts at driver 525, while CUDA 12.6 Update 3 corresponds to 560.35.05. Features that depend on newer driver functionality may need the corresponding branch driver even when minor-version compatibility applies. The CUDA Version field in the full nvidia-smi table is the maximum runtime level exposed by the driver, not necessarily the installed toolkit version shown by nvcc --version.

Add CUDA to PATH for NVIDIA Repository Installs

Skip this subsection if you installed nvidia-cuda-toolkit from Debian’s repository. NVIDIA repository packages install the active toolkit under /usr/local/cuda. Add only its binary directory to your shell PATH; APT packages configure their runtime libraries without a global LD_LIBRARY_PATH.

if ! grep -qxF '# >>> CUDA Toolkit PATH >>>' ~/.bashrc; then
  printf '\n# >>> CUDA Toolkit PATH >>>\nexport PATH=/usr/local/cuda/bin${PATH:+:${PATH}}\n# <<< CUDA Toolkit PATH <<<\n' >> ~/.bashrc
fi

export PATH=/usr/local/cuda/bin${PATH:+:${PATH}}

The final export updates the current shell. New terminal sessions load the managed block from ~/.bashrc.

Check the CUDA Compiler

nvcc --version

The output should name the NVIDIA CUDA compiler and show a release line. The current NVIDIA repository reports CUDA 13.3.x on Debian 13 and Debian 12, while its legacy Debian 11 feed reports CUDA 12.6.x. Debian repository installs report the toolkit branch packaged for that Debian release.

Confirm which compiler path your shell is using:

command -v nvcc

Debian repository installs normally return /usr/bin/nvcc. NVIDIA repository installs normally return /usr/local/cuda/bin/nvcc.

Test CUDA with a Sample Program on Debian

A small CUDA program confirms that the compiler, runtime libraries, driver, and GPU can work together. This test requires a compatible NVIDIA GPU; systems with the toolkit only can compile code but cannot run the GPU kernel successfully.

Create a CUDA Hello World Program

Create a unique temporary directory so the example cannot overwrite a source file in your current working directory. Keep the same terminal open through the cleanup step so SAMPLE_DIR remains defined:

if SAMPLE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/cuda-hello-world.XXXXXXXX")"; then
  cat <<'EOF' > "$SAMPLE_DIR/helloworld.cu"
#include <stdio.h>
#include <cuda_runtime.h>

static int checkCuda(cudaError_t result, const char *operation) {
    if (result != cudaSuccess) {
        fprintf(stderr, "%s failed: %s\n", operation, cudaGetErrorString(result));
        return 0;
    }
    return 1;
}

__global__ void helloFromGPU(void) {
    printf("Hello World from GPU!\n");
}

int main(void) {
    int deviceCount = 0;
    if (!checkCuda(cudaGetDeviceCount(&deviceCount), "cudaGetDeviceCount")) {
        return 1;
    }
    if (deviceCount == 0) {
        fprintf(stderr, "No CUDA-capable GPU detected.\n");
        return 1;
    }

    printf("Hello World from CPU!\n");
    helloFromGPU<<<1, 10>>>();
    if (!checkCuda(cudaGetLastError(), "kernel launch")) {
        return 1;
    }
    if (!checkCuda(cudaDeviceSynchronize(), "cudaDeviceSynchronize")) {
        return 1;
    }
    return 0;
}
EOF
  printf 'Sample directory: %s\n' "$SAMPLE_DIR"
else
  echo "Unable to create a temporary CUDA sample directory." >&2
fi

Compile and Run the CUDA Program

nvcc "${SAMPLE_DIR:?Run the sample creation step first}/helloworld.cu" \
  -o "${SAMPLE_DIR:?Run the sample creation step first}/helloworld" &&
"${SAMPLE_DIR:?Run the sample creation step first}/helloworld"

Compilation alone proves that nvcc and the development files are usable. A complete runtime pass prints one CPU line and ten GPU lines, then exits with status zero. On a hardwareless build system, the executable instead returns a clear device or driver error; do not treat that expected limitation as GPU runtime proof.

Remove the sample files when you no longer need them:

case "${SAMPLE_DIR:-}" in
  "${TMPDIR:-/tmp}"/cuda-hello-world.*)
    if [ -d "$SAMPLE_DIR" ] && [ ! -L "$SAMPLE_DIR" ]; then
      if rm -f -- "$SAMPLE_DIR/helloworld" "$SAMPLE_DIR/helloworld.cu" && \
        rmdir -- "$SAMPLE_DIR"; then
        unset SAMPLE_DIR
      else
        echo "Cleanup incomplete; retained path: $SAMPLE_DIR" >&2
      fi
    else
      echo "Sample path is not a normal directory; nothing removed." >&2
    fi
    ;;
  *) echo "Sample directory variable is missing or unexpected; nothing removed." >&2 ;;
esac

Update or Remove CUDA on Debian

Both documented methods are APT-managed, so routine updates use Debian’s normal package workflow. Removal differs slightly depending on whether you also want to remove NVIDIA driver packages.

Update CUDA Packages

Update only the top-level package used by your method. Simulate the transaction first so a moving metapackage does not cross a toolkit branch or change driver packages unexpectedly.

Update the Debian Repository Toolkit

sudo apt update &&
apt-get -s install --no-install-recommends --only-upgrade nvidia-cuda-toolkit

If the preview preserves the toolkit-only package set, apply the targeted upgrade:

sudo apt install --no-install-recommends --only-upgrade nvidia-cuda-toolkit

Update the NVIDIA Repository Toolkit

sudo apt update &&
apt-get -s install --only-upgrade cuda-toolkit

If the preview keeps the intended toolkit branch and driver packages unchanged, apply the targeted upgrade:

sudo apt install --only-upgrade cuda-toolkit

If you installed the full cuda metapackage, use cuda in place of cuda-toolkit and review the simulated driver changes. For a fixed branch, use its exact metapackage, such as cuda-toolkit-13-3. Before a broad system upgrade while NVIDIA’s priority pin is active, inspect whether it would replace toolkit or driver packages:

apt-get -s upgrade

Review the complete simulation for cuda, nvidia, libcuda, libcu*, libnv*, and nsight package changes. If it lists a driver replacement, confirm that the new branch supports your GPU and CUDA workload before running the real full-system upgrade.

Remove Debian Repository CUDA Packages

Preview and remove the Debian toolkit package first:

apt-get -s purge nvidia-cuda-toolkit

If the preview removes the intended toolkit metapackage without unrelated software, apply it:

sudo apt purge nvidia-cuda-toolkit

Keep nvidia-driver when another desktop, compute, or rendering workload uses it. If this guide installed the driver specifically for CUDA and you intend to remove it too, preview that separate transaction before confirming:

apt-get -s purge nvidia-driver

Only when the preview confirms that no other workload loses a required driver, apply the removal:

sudo apt purge nvidia-driver

Remove NVIDIA Repository CUDA Packages

For the toolkit-only path, purge the same top-level metapackage you installed. Replace cuda-toolkit with a versioned name such as cuda-toolkit-13-3 when that is the installed package:

apt-get -s purge cuda-toolkit

If the preview matches the toolkit package you intended to remove, apply it with that same package name:

sudo apt purge cuda-toolkit

If you installed the full cuda metapackage and want to remove its toolkit-plus-driver dependency set, purge that exact metapackage instead. A driver that was already marked as manually installed should remain outside the automatic dependency set, but verify the preview before continuing:

apt-get -s purge cuda

If the preview contains only the full CUDA dependency set you want to remove, apply it:

sudo apt purge cuda

Review and Remove Unneeded CUDA Dependencies

After removing the top-level package from either method, APT may leave toolkit libraries and tools that were installed automatically. Review the dependency cleanup separately:

APT can have unrelated packages already marked as automatic. Preview autoremove and continue only when every proposed removal belongs to the CUDA method and no other workload needs it.

apt-get -s autoremove --purge

Only after reviewing the complete list, run the real dependency cleanup:

sudo apt autoremove --purge

Remove NVIDIA Repository Configuration

Remove NVIDIA’s repository only when no remaining NVIDIA-repository package needs it. Inspect the package-owned source, key, and pin paths before purging the bootstrap package:

dpkg -L cuda-keyring | grep -E '/(sources.list.d|keyrings|preferences.d)/'
apt-get -s purge cuda-keyring

If the preview removes only the repository bootstrap and its owned source, key, and pin, apply the purge and refresh APT:

sudo apt purge cuda-keyring && sudo apt update

If you added the PATH block from this guide, inspect its exact lines first. The cleanup below creates a uniquely named backup and removes only the known managed-marker and legacy lines; it does not use an open-ended range that could erase unrelated shell settings.

grep -nE 'CUDA Toolkit PATH|^# CUDA Toolkit path$|/usr/local/cuda/(bin|lib64)' "$HOME/.bashrc"

If the output contains the exact managed or legacy lines shown here, back up the file and remove them with a fail-closed subshell. A symbolic-link .bashrc is left untouched so you can edit its real dotfile target deliberately.

(
  set -eu
  if [ -L "$HOME/.bashrc" ] || [ ! -f "$HOME/.bashrc" ]; then
    echo "Refusing to edit a missing or symbolic-link .bashrc" >&2
    exit 1
  fi

  CUDA_BASHRC_BACKUP="$(mktemp "$HOME/.bashrc.cuda-backup.XXXXXXXX")"
  cp -p -- "$HOME/.bashrc" "$CUDA_BASHRC_BACKUP"
  sed -i \
    -e '/^# >>> CUDA Toolkit PATH >>>$/d' \
    -e '/^export PATH=\/usr\/local\/cuda\/bin\${PATH:+:\${PATH}}$/d' \
    -e '/^# <<< CUDA Toolkit PATH <<<$/d' \
    -e '/^# CUDA Toolkit path$/d' \
    -e '/^export PATH=\/usr\/local\/cuda\/bin:\$PATH$/d' \
    -e '/^export LD_LIBRARY_PATH=\/usr\/local\/cuda\/lib64:\$LD_LIBRARY_PATH$/d' \
    "$HOME/.bashrc"
  printf 'Backup: %s\n' "$CUDA_BASHRC_BACKUP"
)

Verify CUDA Removal

hash -r
command -v nvcc || echo "nvcc not found"
dpkg-query -W -f='${db:Status-Abbrev}\t${binary:Package}\n' \
  cuda 'cuda-*' 'nvidia-cuda-*' 'libcublas*' 'libcudart*' 'libcufft*' \
  'libcupti*' 'libcurand*' 'libcusolver*' 'libcusparse*' 'libcuinj*' \
  'libaccinj*' 'libcub*' 'libcufile*' 'libthrust*' 'libnpp*' 'libnvblas*' \
  'libnvfatbin*' 'libnvjitlink*' 'libnvjpeg*' 'libnvrtc*' 'libnvtoolsext*' \
  'libnvvm*' 'nsight*' 'nvidia-opencl-*' 'nvidia-profiler*' \
  'nvidia-visual-profiler*' 2>/dev/null
grep -R "developer.download.nvidia.com/compute/cuda" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null \
  || echo "NVIDIA CUDA repository not configured"
find /usr/local -maxdepth 1 -name 'cuda*' -print
sudo apt-get check

After a complete toolkit cleanup, command -v prints nvcc not found, the package query shows no ii or rc entries for the toolkit components you removed, and find prints no NVIDIA CUDA prefix. The repository check prints its fallback only when you also removed cuda-keyring; retaining that repository is valid when other NVIDIA packages still use it. Driver packages can remain intentionally when another workload needs them. Open a new terminal before treating PATH absence as final shell proof.

Troubleshoot CUDA on Debian

APT Cannot Find nvidia-cuda-toolkit

If the Debian repository method reports no candidate for nvidia-cuda-toolkit, the required components are probably missing from your Debian sources. Check the active source entries:

grep -R "^Components:" /etc/apt/sources.list.d/ 2>/dev/null
grep -hE "^[[:space:]]*deb " /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null

Debian 13 and Debian 12 should include main contrib non-free non-free-firmware. Debian 11 should include main contrib non-free. After correcting the sources, refresh APT and recheck the package candidate.

NVIDIA Repository Shows a Signed-By Conflict

A Signed-By conflict means more than one source file points to the same NVIDIA CUDA repository with different keyring settings. List the matching files:

grep -R "developer.download.nvidia.com/compute/cuda" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

Check whether cuda-keyring owns the active source and key, then identify the exact duplicate shown by the first command:

dpkg -s cuda-keyring
dpkg -L cuda-keyring | grep -E '/(sources.list.d|keyrings)/'

If the duplicate is the legacy nvidia-cuda.sources file created by an older revision of this guide, remove that one file and retest. Do not delete a package-owned source or an intentional local repository:

LEGACY_CUDA_SOURCE=/etc/apt/sources.list.d/nvidia-cuda.sources
if [ -L "$LEGACY_CUDA_SOURCE" ]; then
  echo "Refusing to remove a symbolic-link source: $LEGACY_CUDA_SOURCE" >&2
elif [ -f "$LEGACY_CUDA_SOURCE" ]; then
  if SOURCE_OWNER="$(dpkg-query -S "$LEGACY_CUDA_SOURCE" 2>&1)"; then
    echo "Refusing to remove package-owned source: $SOURCE_OWNER" >&2
  else
    QUERY_STATUS=$?
    if [ "$QUERY_STATUS" -ne 1 ]; then
      echo "Package ownership query failed: $SOURCE_OWNER" >&2
    elif grep -q "developer.download.nvidia.com/compute/cuda" "$LEGACY_CUDA_SOURCE"; then
      sudo rm -- "$LEGACY_CUDA_SOURCE" && sudo apt update
    else
      echo "Source does not point to NVIDIA CUDA; nothing removed." >&2
    fi
  fi
else
  echo "Legacy NVIDIA CUDA source not found; nothing removed." >&2
fi

APT Mentions cuda-debian12.pin or Another CUDA Pin

NVIDIA’s local repository installers can create CUDA pin files under /etc/apt/preferences.d/. The current cuda-keyring network-repository package also owns cuda-repository-pin-600, so the filename alone does not prove that a pin is stale. Inspect both its contents and package ownership before removing anything:

grep -R "cuda" /etc/apt/preferences /etc/apt/preferences.d/ 2>/dev/null
dpkg-query -S /etc/apt/preferences.d/cuda-repository-pin-600

Keep the pin when dpkg-query reports cuda-keyring. If another installed local-repository package owns a stale pin, purge that owner package instead of deleting one of its files by hand. Only run the guarded cleanup below when the ownership query reports no path and the inspected contents belong to an obsolete local repository. It refuses symbolic links and package-owned files, creates a unique backup, and stops if APT cannot refresh:

(
  set -eu
  PIN_FILE=/etc/apt/preferences.d/cuda-repository-pin-600

  if [ -L "$PIN_FILE" ] || [ ! -f "$PIN_FILE" ]; then
    echo "Refusing to move a missing or symbolic-link pin: $PIN_FILE" >&2
    exit 1
  fi

  if PIN_OWNER="$(dpkg-query -S "$PIN_FILE" 2>&1)"; then
    echo "Refusing to move package-owned pin: $PIN_OWNER" >&2
    exit 1
  else
    QUERY_STATUS=$?
    if [ "$QUERY_STATUS" -ne 1 ]; then
      echo "Package ownership query failed: $PIN_OWNER" >&2
      exit "$QUERY_STATUS"
    fi
  fi

  PIN_BACKUP="/var/backups/cuda-repository-pin-600.linuxcapable-backup.$(date +%Y%m%d%H%M%S)"
  if ! sudo test -d /var/backups; then
    echo "Backup directory is missing: /var/backups" >&2
    exit 1
  fi

  if sudo test -e "$PIN_BACKUP" || sudo test -L "$PIN_BACKUP"; then
    echo "Backup path already exists: $PIN_BACKUP" >&2
    exit 1
  fi

  sudo cp --preserve=all -- "$PIN_FILE" "$PIN_BACKUP"
  sudo rm -- "$PIN_FILE"
  sudo apt update
  printf 'Backup: %s\n' "$PIN_BACKUP"
)

nvidia-smi Is Missing or Does Not Detect the GPU

First distinguish missing hardware from a driver problem:

lspci -nn | grep -i nvidia

If this command prints no NVIDIA device, driver reinstall attempts cannot create GPU hardware. When the device is present, check the command and loaded-module state:

command -v nvidia-smi || echo "nvidia-smi not installed"
lsmod | grep -E '^(nvidia|nouveau)'

If no NVIDIA modules appear, inspect DKMS status and recent kernel messages:

dkms status
sudo dmesg | grep -i nvidia

Common causes include missing headers for the running kernel, Secure Boot blocking the module, an unsupported GPU for the selected driver branch, or a reboot that has not happened yet. Continue with the Secure Boot and module diagnostics below before reinstalling packages.

Secure Boot Opens the MOK Management Screen

When Secure Boot is enabled, Debian may ask you to enroll a Machine Owner Key (MOK) before the NVIDIA kernel module can load. Check the current Secure Boot state, module signer, and kernel messages:

command -v mokutil >/dev/null && mokutil --sb-state
modinfo -F signer nvidia 2>/dev/null
sudo journalctl -k -b | grep -Ei 'nvidia|verification|lockdown'

Complete the package-generated MOK enrollment during reboot, then repeat modinfo, lsmod, and nvidia-smi. Disabling Secure Boot changes the machine’s security posture and should not be the routine fix; use the dedicated Debian NVIDIA driver guide for driver-package, signing, and recovery details.

nvcc Command Not Found

Check the expected compiler location for your installation method:

ls /usr/bin/nvcc /usr/local/cuda/bin/nvcc 2>/dev/null

If /usr/local/cuda/bin/nvcc exists, add the NVIDIA repository PATH lines from the verification section. If neither path exists, reinstall the toolkit package for your method:

sudo apt install --no-install-recommends --reinstall nvidia-cuda-toolkit

For an NVIDIA repository install, reinstall the same top-level package already shown by the package-source check. Do not add the moving cuda-toolkit metapackage merely to repair a fixed branch. For the moving metapackage, use:

sudo apt install --reinstall cuda-toolkit

For the fixed CUDA 13.3 branch on Debian 13 or Debian 12, use only:

sudo apt install --reinstall cuda-toolkit-13-3

For the fixed CUDA 12.6 branch on Debian 11, use only:

sudo apt install --reinstall cuda-toolkit-12-6

Nouveau Still Loads After Installing NVIDIA Drivers

If Nouveau remains active after installing the NVIDIA driver, inspect loaded modules, DKMS state, and any blacklist already supplied by a package:

lsmod | grep -E '^(nouveau|nvidia)'
dkms status
grep -R "blacklist nouveau" /etc/modprobe.d/ /usr/lib/modprobe.d/ /lib/modprobe.d/ 2>/dev/null

If the installed driver package did not create a working blacklist and the diagnostics confirm that Nouveau is the conflict, create a uniquely named article-owned file. The fail-closed subshell refuses regular files, symbolic links, and paths created during the check; shell no-clobber mode prevents the final write from overwriting an existing path:

(
  set -eu
  NOUVEAU_DROPIN=/etc/modprobe.d/linuxcapable-cuda-nouveau.conf
  DROPIN_CONTENT="$(mktemp)"
  trap 'rm -f -- "$DROPIN_CONTENT"' EXIT
  printf 'blacklist nouveau\noptions nouveau modeset=0\n' > "$DROPIN_CONTENT"

  if sudo test -e "$NOUVEAU_DROPIN" || sudo test -L "$NOUVEAU_DROPIN"; then
    echo "Refusing to overwrite an existing path: $NOUVEAU_DROPIN" >&2
    exit 1
  fi

  sudo sh -c 'set -eu; set -C; umask 022; cat "$1" > "$2"' \
    sh "$DROPIN_CONTENT" "$NOUVEAU_DROPIN"
  if ! sudo cmp -s -- "$DROPIN_CONTENT" "$NOUVEAU_DROPIN"; then
    sudo rm -- "$NOUVEAU_DROPIN"
    echo "Drop-in verification failed; the new file was removed." >&2
    exit 1
  fi

  echo "Created and verified $NOUVEAU_DROPIN"
)

Only when the command confirms that it created and verified the new file, rebuild the initial ramdisk and reboot. The reboot runs only if the rebuild succeeds:

sudo update-initramfs -u && sudo reboot

After rebooting, lsmod | grep nouveau should return no output, and lsmod | grep nvidia should show NVIDIA modules instead.

If the manual blacklist does not solve the problem, verify that the file still contains only the exact two article-owned lines before removing it. The rollback refuses a changed file and reboots only after rebuilding the initial ramdisk successfully:

(
  set -eu
  NOUVEAU_DROPIN=/etc/modprobe.d/linuxcapable-cuda-nouveau.conf
  EXPECTED_CONTENT="$(mktemp)"
  trap 'rm -f -- "$EXPECTED_CONTENT"' EXIT
  printf 'blacklist nouveau\noptions nouveau modeset=0\n' > "$EXPECTED_CONTENT"

  if sudo test -L "$NOUVEAU_DROPIN" || \
     ! sudo cmp -s -- "$EXPECTED_CONTENT" "$NOUVEAU_DROPIN"; then
    echo "Refusing to remove a missing, symbolic-link, or changed drop-in: $NOUVEAU_DROPIN" >&2
    exit 1
  fi

  sudo rm -- "$NOUVEAU_DROPIN"
  sudo update-initramfs -u
  sudo reboot
)

Conclusion

Debian’s package archive and NVIDIA’s CUDA repository provide distinct toolkit branches for different project and GPU requirements. Confirm the installed package source and nvcc first; only a compatible NVIDIA GPU, working driver, and error-checked sample can prove runtime execution. For larger compiler and runtime tests, continue with the NVIDIA CUDA Samples documentation.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show our tutorials more often in Top Stories and mark them as preferred in AI Mode and AI Overviews when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee

5 thoughts on “How to Install CUDA on Debian 13, 12 and 11”

  1. Hello Joshua. For the time being I only wanted to say express gratitude for this fantastic guide. I am not sure that I ever before saw any guide put together in so much detail as yours.

    I’ve been messing around “turqboquant-pytorch” on ancient GTX 1070 on LMDE 7. It’s complaining that CUDA 12.4 is too old, but of course it doesn’t state which version I need :]. Pascal likely has nothing new to offer on 12.* (likely even on 11.*) but software complaining about software versions.

    Anyhow, I was thinking about hopping from LMDE 7 to something else (anything other than a rolling distro) but I’ll give this guide a try before I take a plunge into the unknown and possibly completely mess up this system.

    I would like to use MX Linux as my daily driver (even though it has a few annoying flaws) but I also like to mess with local LLM and for that I will likely have to bite the bullet and use a rolling distro. Which I really don’t want to do due to the constant massive stream of updates.

    Anyhow, thanks. If and when I try this out on LMDE 7/1070 I’ll certainly post back here. For the science!

    Reply
  2. Sun Feb 23 14:18:29 2025
    +—————————————————————————————+
    | NVIDIA-SMI 535.216.03 Driver Version: 535.216.03 CUDA Version: 12.2 |
    |—————————————–+———————-+———————-+
    | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
    | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
    | | | MIG M. |
    |=========================================+======================+======================|
    | 0 NVIDIA GeForce GTX 1050 Ti On | 00000000:07:00.0 On | N/A |
    | 35% 36C P0 N/A / 75W | 2196MiB / 4096MiB | 9% Default |
    | | | N/A |
    +—————————————–+———————-+———————-+

    +—————————————————————————————+
    | Processes: |
    | GPU GI CI PID Type Process name GPU Memory |
    | ID ID Usage |
    |=======================================================================================|
    | 0 N/A N/A 1309 G /usr/lib/xorg/Xorg 1188MiB |
    | 0 N/A N/A 1960 G cinnamon 368MiB |
    | 0 N/A N/A 2516 G /usr/lib/thunderbird/thunderbird 244MiB |
    | 0 N/A N/A 74410 G /usr/bin/firefox.real 325MiB |
    +—————————————————————————————+
    late to the party, but it all workd for me, Thanks.

    Reply
    • Thanks for the confirmation, Steve. Your output shows the 535.216.03 driver detecting the GTX 1050 Ti and reporting CUDA 12.2 as the maximum runtime level exposed by that driver. That is useful confirmation for readers with similar Pascal hardware. Check the installed toolkit separately with nvcc --version.

      Reply
    • Hi Fred. Which Debian release, NVIDIA GPU, installation method, and exact error did you encounter? The output from apt-cache policy nvidia-cuda-toolkit cuda-toolkit, nvcc --version, and nvidia-smi, if available, would help separate a package-source problem from a toolkit or driver problem.

      Reply
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<a href="https://example.com">link</a> link
<blockquote>quote</blockquote> quote block

Add to the discussion

Questions, fixes, command output, and version notes help keep this guide current.

Verify before posting: