How to Install Kotlin on Fedora 44

Install Kotlin on Fedora 44 without mixing compiler paths or update owners. Choose a per-user toolchain, a shared /opt installation, or a store-managed package, then confirm the result by compiling a small .kt program into a runnable JAR with Fedora's OpenJDK toolchain.

PublishedAuthorJoshua JamesRead time9 minGuide typeFedora

Fedora 44 does not package the Kotlin command-line compiler in its default repositories, so the source you choose also determines how kotlinc is updated and removed. For most developers, the simplest way to install Kotlin on Fedora Linux is SDKMAN because it handles per-user versions without placing compiler files in system paths.

A shared /opt path suits multi-user systems, while the store-managed Snap provides automatic refreshes but uses classic confinement and currently supports only x86_64. Every workflow uses Fedora’s OpenJDK 25 and finishes with the same JVM compile-and-run check.

Install Kotlin on Fedora Linux

Choose a Kotlin Installation Method

MethodSource and ScopeUpdate OwnerChoose This Method When
SDKMANSDKMAN-managed JetBrains compiler for the current usersdk upgrade kotlinYou develop with Kotlin or switch versions between projects
JetBrains archiveOfficial ZIP and SHA-256 sidecar under /optupdate-kotlin-compiler helperSeveral users or tools need one stable system path
SnapVerified JetBrains Snap with classic confinement and a current x86_64 channelAutomatic snapd refreshesYou prefer a store-managed installation

Install one method unless you deliberately need several. Each method can expose a command named kotlinc, and the shell uses whichever copy appears first on PATH. Check for an existing compiler before changing the system:

type -a kotlinc 2>/dev/null || echo "No Kotlin compiler is currently on PATH"

The current Snap channel publishes an amd64 build, which Fedora identifies as x86_64. On aarch64 or another architecture, skip the Snap method and confirm current upstream and JDK support before choosing SDKMAN or the archive.

Fedora Atomic desktops such as Silverblue and Kinoite use a different installation boundary. Create a Toolbx development container and install Java and Kotlin inside the same container instead of applying the host-level /opt or Snap workflow unchanged.

Prepare Fedora and Install Java

A full Fedora update is optional and separate from the Kotlin prerequisite. Review the transaction before applying it because unrelated packages can change, and a kernel or core-library update may require a reboot:

sudo dnf upgrade --refresh

The following commands use sudo for system changes. Review the separate steps for managing sudo access on Fedora instead of granting administrator access only to bypass a permission error.

Install Fedora’s OpenJDK 25 development package. It provides the Java runtime, Java compiler, and JAR tools required by Kotlin/JVM:

sudo dnf install java-25-openjdk-devel

Confirm the installed RPM and both Java commands before installing Kotlin:

rpm -q java-25-openjdk-devel
java --version
javac --version

The RPM release changes with Fedora updates, but both version commands should report OpenJDK major 25. Projects that require another Java major should select and verify it first with the OpenJDK installation guide for Fedora.

Install Kotlin with SDKMAN

Kotlin’s official command-line documentation presents SDKMAN as the easier installation path on Unix-like systems. SDKMAN owns candidate downloads, version selection, and updates inside the current user’s home directory, where it can maintain several Kotlin versions side by side.

Install the SDKMAN Kotlin Candidate

Complete the SDKMAN setup on Fedora first when the sdk shell function is unavailable. Then load SDKMAN in the current shell and install Kotlin:

Run SDKMAN and its candidate commands as your normal user, not with sudo. A root-owned SDKMAN installation is separate from the one used by your normal shell.

source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk version
sdk install kotlin

Verify the SDKMAN Compiler

Check SDKMAN’s selected candidate, the path used by this shell, and the compiler version:

sdk current kotlin
command -v kotlinc
kotlinc -version

A successful installation reports the current Kotlin version, a path below ~/.sdkman/candidates/kotlin/current/bin, and the JVM used by kotlinc. Kotlin and Java patch versions will change as their maintainers publish updates.

Run sdk list kotlin to see exact identifiers available for this machine. Use sdk install kotlin <version> to add one, sdk use kotlin <version> for the current shell, or sdk default kotlin <version> for future shells.

Install the Verified JetBrains Kotlin Archive

This advanced method installs JetBrains’ official compiler archive into a versioned directory and keeps /opt/kotlin as the stable path. A named helper makes the same guarded release lookup, integrity check, staging, and promotion sequence reusable for future updates.

Install the Archive Prerequisites

Install the download and extraction tools, then confirm that the temporary and final filesystems have enough free space:

sudo dnf install curl ca-certificates unzip
df -h /var/tmp /opt

Create the Kotlin Archive Helper

The setup block refuses to replace a symlink, directory, or helper without this workflow’s exact marker. It creates the script in a temporary file, checks its Bash syntax, and installs the finished command as /usr/local/bin/update-kotlin-compiler:

(
  set -euo pipefail
  helper='/usr/local/bin/update-kotlin-compiler'
  helper_marker='# Managed by the LinuxCapable Kotlin archive workflow'
  helper_tmp="$(mktemp)"
  trap 'rm -f -- "$helper_tmp"' EXIT

  if sudo test -e "$helper" || sudo test -L "$helper"; then
    if ! sudo test -f "$helper" || sudo test -L "$helper" ||
       ! sudo grep -qxF "$helper_marker" "$helper"; then
      printf 'Refusing unmanaged helper: %s\n' "$helper" >&2
      exit 1
    fi
  fi

  cat > "$helper_tmp" <<'KOTLIN_HELPER'
#!/usr/bin/env bash
# Managed by the LinuxCapable Kotlin archive workflow
set -euo pipefail

work_dir=''
stage_dir=''

cleanup() {
  if [ -n "$work_dir" ] && [ -d "$work_dir" ]; then
    rm -rf -- "$work_dir"
  fi
  if [ -n "$stage_dir" ] && sudo test -d "$stage_dir"; then
    sudo rm -rf -- "$stage_dir"
  fi
}
trap cleanup EXIT

main() {
  local marker='.linuxcapable-kotlin-compiler'
  local profile_file='/etc/profile.d/kotlin.sh'
  local profile_content
  local version
  local install_dir
  local active_target=''
  local archive
  local base_url
  local checksum=''
  local checksum_name=''

  profile_content=$'# Managed by the LinuxCapable Kotlin archive workflow\nexport PATH="/opt/kotlin/bin:$PATH"'

  version="$(
    curl -fsSIL -o /dev/null -w '%{url_effective}' \
      https://github.com/JetBrains/kotlin/releases/latest |
      sed -E 's#.*/tag/v##'
  )"
  if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    printf 'Refusing unexpected or prerelease Kotlin version: %s\n' "$version" >&2
    return 1
  fi

  if sudo test -e "$profile_file" || sudo test -L "$profile_file"; then
    if ! sudo test -f "$profile_file" || sudo test -L "$profile_file" ||
       [ "$(sudo cat "$profile_file")" != "$profile_content" ]; then
      printf 'Refusing unmanaged profile file: %s\n' "$profile_file" >&2
      return 1
    fi
  fi

  if [ -L /opt/kotlin ]; then
    active_target="$(readlink -f /opt/kotlin 2>/dev/null || true)"
    if [[ ! "$active_target" =~ ^/opt/kotlin-[0-9]+\.[0-9]+\.[0-9]+$ ]] ||
       ! sudo test -f "$active_target/$marker"; then
      printf 'Refusing unmanaged /opt/kotlin target: %s\n' "$active_target" >&2
      return 1
    fi
  elif [ -e /opt/kotlin ]; then
    printf '%s\n' '/opt/kotlin exists and is not a symlink.' >&2
    return 1
  fi

  install_dir="/opt/kotlin-${version}"
  if sudo test -e "$install_dir" || sudo test -L "$install_dir"; then
    if ! sudo test -d "$install_dir" || sudo test -L "$install_dir" ||
       ! sudo test -f "$install_dir/$marker" ||
       ! sudo test -x "$install_dir/bin/kotlinc"; then
      printf 'Refusing existing or incomplete directory: %s\n' "$install_dir" >&2
      return 1
    fi

    sudo ln -sfnT "$install_dir" /opt/kotlin
    printf '%s\n' "$profile_content" | sudo tee "$profile_file" >/dev/null
    sudo chmod 0644 "$profile_file"
    if [ "$active_target" = "$install_dir" ]; then
      printf 'Kotlin %s is already active at %s\n' "$version" "$install_dir"
    else
      printf 'Activated existing Kotlin %s at %s\n' "$version" "$install_dir"
    fi
    return 0
  fi

  work_dir="$(mktemp -d /var/tmp/kotlin-download.XXXXXX)"
  stage_dir="$(sudo mktemp -d "/opt/.kotlin-${version}.XXXXXX")"
  archive="kotlin-compiler-${version}.zip"
  base_url="https://github.com/JetBrains/kotlin/releases/download/v${version}"

  cd "$work_dir"
  curl -fL --retry 3 --retry-delay 2 -o "$archive" "${base_url}/${archive}"
  curl -fL --retry 3 --retry-delay 2 -o "${archive}.sha256" \
    "${base_url}/${archive}.sha256"

  IFS=' ' read -r checksum checksum_name < "${archive}.sha256" || true
  checksum_name="${checksum_name#\*}"
  if [[ ! "$checksum" =~ ^[[:xdigit:]]{64}$ ]] ||
     { [ -n "$checksum_name" ] && [ "$checksum_name" != "$archive" ]; }; then
    printf '%s\n' 'The published SHA-256 record is invalid.' >&2
    return 1
  fi

  printf '%s  %s\n' "$checksum" "$archive" | sha256sum -c -
  unzip -tq "$archive" >/dev/null
  sudo unzip -q "$archive" -d "$stage_dir"

  if ! sudo test -x "$stage_dir/kotlinc/bin/kotlinc"; then
    printf '%s\n' 'The archive did not contain kotlinc/bin/kotlinc.' >&2
    return 1
  fi

  printf '%s\n' 'Managed by the LinuxCapable Kotlin archive workflow' |
    sudo tee "$stage_dir/kotlinc/$marker" >/dev/null
  sudo chmod 0644 "$stage_dir/kotlinc/$marker"
  sudo mv -T "$stage_dir/kotlinc" "$install_dir"
  sudo chmod 0755 "$install_dir"
  sudo rmdir "$stage_dir"
  stage_dir=''

  sudo ln -sfnT "$install_dir" /opt/kotlin
  printf '%s\n' "$profile_content" | sudo tee "$profile_file" >/dev/null
  sudo chmod 0644 "$profile_file"
  printf 'Installed Kotlin %s at %s\n' "$version" "$install_dir"
}

main "$@"
KOTLIN_HELPER

  bash -n "$helper_tmp"
  sudo install -o root -g root -m 0755 "$helper_tmp" "$helper"
  command -v update-kotlin-compiler
)

The final line should print /usr/local/bin/update-kotlin-compiler. The helper resolves JetBrains’ current stable release, rejects unexpected tags and unmanaged paths, and stages a new version under /opt before switching the stable symlink.

Run the Archive Helper and Verify Kotlin

Run the friendly command to download and install the current stable compiler:

update-kotlin-compiler

With Kotlin 2.4.10 as the current stable release, the checksum and installation lines are:

kotlin-compiler-2.4.10.zip: OK
Installed Kotlin 2.4.10 at /opt/kotlin-2.4.10

The SHA-256 result confirms that the downloaded ZIP matches JetBrains’ published sidecar; it does not replace trust in JetBrains as the source. A checksum or archive failure stops before the helper changes the active /opt/kotlin symlink.

Load the managed profile in the current shell, clear Bash’s command cache, and verify both the stable and resolved paths:

. /etc/profile.d/kotlin.sh
hash -r
command -v kotlinc
readlink -f "$(command -v kotlinc)"
kotlinc -version

The command path should be /opt/kotlin/bin/kotlinc, while the resolved path should sit below a marked /opt/kotlin-<version> directory. Rerunning the helper when the newest release is already active produces a no-op result similar to:

Kotlin 2.4.10 is already active at /opt/kotlin-2.4.10

Install Kotlin with Snap

The verified Kotlin Snap is published by JetBrains. It uses classic confinement, which grants broad host access similar to a traditional development package, and its current stable channel is available for x86_64 systems.

Prepare snapd on Fedora

Systems that already completed the Snap setup on Fedora can skip this block. Otherwise, install snapd, activate its socket, create Fedora’s conventional /snap link only when the path is free, and wait for snapd to finish seeding:

(
  set -euo pipefail

  if ! command -v snap >/dev/null 2>&1; then
    sudo dnf install snapd
  fi

  sudo systemctl enable --now snapd.socket

  if [ ! -e /snap ]; then
    sudo ln -s /var/lib/snapd/snap /snap
  elif [ ! -L /snap ] || [ "$(readlink -f /snap)" != /var/lib/snapd/snap ]; then
    printf '%s\n' 'Inspect the existing /snap path before continuing.' >&2
    exit 1
  fi

  sudo snap wait system seed.loaded
)

Open a new terminal or sign out and back in after first installing snapd. A new login shell reads /etc/profile.d/snapd.sh and adds the Snap command directory to PATH.

Inspect and Install the Kotlin Snap

Confirm this machine’s architecture and inspect the store record. On Fedora 44 x86_64, the verified listing identifies JetBrains as the publisher, Kotlin 2.4.10 in the latest/stable channel, and classic confinement. If the publisher, channel, or confinement differs, stop and confirm that you selected the intended store package before installing it:

uname -m
snap info kotlin

The following guarded block installs the Snap only on this method’s supported x86_64 architecture:

(
  set -eu
  if [ "$(uname -m)" != x86_64 ]; then
    printf '%s\n' 'The current Kotlin Snap is not published for this architecture.' >&2
    exit 1
  fi

  sudo snap install kotlin --classic
)

Verify the Kotlin Snap

Verify the installed channel, run the compiler through snapd immediately, and inspect the aliases exported by the package:

snap list kotlin
snap run kotlin.kotlinc -version
snap aliases kotlin

A Fedora 44 login shell resolves the bare alias as /var/lib/snapd/snap/bin/kotlinc. Check it from the new terminal before using the compile-and-run test in the next section:

command -v kotlinc
kotlinc -version

Compile and Run Kotlin on Fedora

A version check proves that the compiler starts. This temporary build also confirms that Kotlin can produce JVM bytecode and Java can run the generated JAR. Snap users should run it from the new terminal where the kotlinc alias is visible.

(
  set -euo pipefail
  demo_dir="$(mktemp -d)"
  trap 'rm -rf -- "$demo_dir"' EXIT

  cat > "$demo_dir/hello.kt" <<'KOTLIN_EOF'
fun main() {
    println("Hello, Kotlin on Fedora!")
}
KOTLIN_EOF

  kotlinc "$demo_dir/hello.kt" -include-runtime -d "$demo_dir/hello.jar"
  java -jar "$demo_dir/hello.jar"
)

Each method prints:

Hello, Kotlin on Fedora!

The -include-runtime option embeds the Kotlin runtime in the JAR so Java can launch it directly. JetBrains documents more targets and flags in the Kotlin command-line compiler reference.

Use Kotlin with Gradle, Maven, or an IDE

The standalone kotlinc command suits scripts, small programs, and compiler diagnostics. Normal Gradle projects pin the Kotlin Gradle plugin in project files and use the project’s Gradle Wrapper, so updating the standalone compiler does not silently change the Kotlin version used by that build.

IntelliJ IDEA and Android Studio also manage Kotlin through their project models. Maven projects should keep the Kotlin plugin version in pom.xml; the Apache Maven setup for Fedora covers the separate mvn toolchain.

Update Kotlin on Fedora

Use the update path owned by the method that installed the active compiler. Confirm that owner with command -v kotlinc before changing anything.

Update Kotlin with SDKMAN

Refresh SDKMAN’s candidate metadata, upgrade Kotlin when a newer stable candidate is available, and confirm the selected result:

source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk update
sdk upgrade kotlin
sdk current kotlin

Update the JetBrains Kotlin Archive

Use this read-only status check to compare the active archive directory with JetBrains’ current stable release:

(
  set -euo pipefail
  latest_version="$(
    curl -fsSIL -o /dev/null -w '%{url_effective}' \
      https://github.com/JetBrains/kotlin/releases/latest |
      sed -E 's#.*/tag/v##'
  )"
  active_target="$(readlink -f /opt/kotlin)"

  if [[ ! "$latest_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] ||
     [[ ! "$active_target" =~ ^/opt/kotlin-[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    printf '%s\n' 'Could not resolve a valid installed or available version.' >&2
    exit 1
  fi

  printf 'Installed Kotlin: %s\n' "${active_target#/opt/kotlin-}"
  printf 'Available Kotlin: %s\n' "$latest_version"
)

When the available version is newer, or to confirm that the active release is current, run the helper:

update-kotlin-compiler

An update prints the SHA-256 success line followed by Installed Kotlin <version> at /opt/kotlin-<version>. A current installation prints Kotlin <version> is already active. Keep an older marked directory until the new compiler and your project builds pass; the guarded removal workflow can delete all retained versions later.

Update Kotlin with Snap

snapd refreshes installed Snaps automatically. These commands show pending refreshes, request one immediately, and confirm the installed channel:

snap refresh --list
sudo snap refresh kotlin
snap list kotlin

Troubleshoot Kotlin on Fedora

Find Which kotlinc Command Is Active

When the version is unexpected, inspect the first executable on PATH, its resolved target, and every other shell match before reinstalling anything:

kotlinc_path="$(command -v kotlinc 2>/dev/null || true)"

if [ -n "$kotlinc_path" ]; then
  resolved_kotlinc="$(readlink -f "$kotlinc_path" 2>/dev/null || true)"
  printf 'Shell command: %s\n' "$kotlinc_path"
  printf 'Resolved path: %s\n' "$resolved_kotlinc"
  rpm -qf "$resolved_kotlinc" 2>/dev/null || \
    echo "The active compiler is not owned by an RPM package"
  kotlinc -version
else
  echo "kotlinc is not on PATH"
fi

type -a kotlinc 2>/dev/null || true
unset kotlinc_path resolved_kotlinc

Paths below ~/.sdkman belong to SDKMAN, /opt/kotlin belongs to the archive helper, and /var/lib/snapd/snap/bin belongs to Snap. Remove or deactivate the unwanted owner instead of repeatedly installing another copy.

Fix kotlinc Not Found after a Snap Install

The snapd package adds its command directory through a login profile. If snap run kotlin.kotlinc -version works but command -v kotlinc returns nothing, open a new terminal or sign out and back in. Then clear any cached miss and check again:

hash -r
command -v kotlinc
kotlinc -version

Fix Java Missing or Mismatched

Reinstall Fedora’s selected development package when Java is absent, then verify that the runtime and compiler use the intended major:

sudo dnf install java-25-openjdk-devel
java --version
javac --version

If several JDKs are installed and the majors differ, select the same release in both Fedora alternatives menus:

sudo alternatives --config java
sudo alternatives --config javac

Persistent custom Java paths need matching JAVA_HOME and PATH values. The Java environment path guide for Fedora covers that separate configuration.

Do Not Bypass a Kotlin Checksum Failure

A failed SHA-256 check means the downloaded ZIP does not match JetBrains’ published sidecar. The helper removes its exact temporary workspace and leaves the previous active version unchanged. Confirm that the official release page and network path are reachable, then rerun the helper; do not extract or install the mismatched archive.

Resolve Archive Ownership Refusals

The archive helper deliberately stops when its command, profile file, stable symlink, or version directory exists without the expected type and marker. Do not delete an unfamiliar path to force the update. Inspect the path named in the error and use type -a kotlinc to determine which installation owns it before moving, backing up, or removing anything.

Remove Kotlin from Fedora

Remove Kotlin with the command set matching its installation source. Fedora’s OpenJDK package remains installed because other JVM applications and build tools may use it.

Remove Kotlin Installed with SDKMAN

Load SDKMAN and list installed candidates before choosing a version:

source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk list kotlin

To keep Kotlin available, set one installed version as the default and remove a different version. Replace both assignments with exact installed identifiers; the guard refuses blank, malformed, or identical values:

kotlin_to_keep='replace-with-installed-version'
kotlin_to_remove='replace-with-installed-version'

if [[ "$kotlin_to_keep" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] &&
   [[ "$kotlin_to_remove" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] &&
   [ "$kotlin_to_keep" != "$kotlin_to_remove" ]; then
  sdk default kotlin "$kotlin_to_keep"
  sdk uninstall kotlin "$kotlin_to_remove"
else
  printf '%s\n' 'Set two different installed Kotlin version identifiers first.' >&2
fi

unset kotlin_to_keep kotlin_to_remove

SDKMAN 5.23 refuses to uninstall a candidate while it is still the current default. If you intend to remove the active and final Kotlin candidate, the following block verifies the exact SDKMAN symlink, temporarily unlinks it, runs SDKMAN’s normal uninstall command, and restores the link if that command fails:

This removes the Kotlin candidate currently selected by SDKMAN. It does not remove SDKMAN or candidates such as Java, Gradle, or Maven.

(
  set -e
  set +u
  source "$HOME/.sdkman/bin/sdkman-init.sh"

  current_link="$SDKMAN_DIR/candidates/kotlin/current"
  if [ ! -L "$current_link" ]; then
    printf '%s\n' 'SDKMAN has no current Kotlin symlink to remove.' >&2
    exit 1
  fi

  kotlin_version="$(basename "$(readlink -f "$current_link")")"
  version_dir="$SDKMAN_DIR/candidates/kotlin/$kotlin_version"
  if [[ ! "$kotlin_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] ||
     [ "$(readlink -f "$current_link")" != "$version_dir" ]; then
    printf '%s\n' 'Refusing an unexpected SDKMAN Kotlin target.' >&2
    exit 1
  fi

  restore_current=1
  restore_link() {
    if [ "$restore_current" -eq 1 ] && [ -d "$version_dir" ] &&
       [ ! -e "$current_link" ] && [ ! -L "$current_link" ]; then
      ln -s "$kotlin_version" "$current_link"
    fi
  }
  trap restore_link EXIT

  rm -- "$current_link"
  sdk uninstall kotlin "$kotlin_version"
  if [ -e "$version_dir" ] || [ -L "$current_link" ]; then
    printf '%s\n' 'SDKMAN left Kotlin state behind; inspect it before continuing.' >&2
    exit 1
  fi
  restore_current=0
  printf 'Removed SDKMAN Kotlin %s\n' "$kotlin_version"
)

Removing a Kotlin candidate does not remove SDKMAN itself. Use the separate SDKMAN guide only when the manager and all of its candidates should also be removed.

Clear Bash’s command cache and confirm whether another installation method still provides Kotlin:

hash -r
command -v kotlinc || echo "kotlinc is no longer on PATH"

Remove the JetBrains Kotlin Archive

Preview the helper, active target, and every directory carrying the archive workflow marker:

command -v update-kotlin-compiler 2>/dev/null || true
readlink -f /opt/kotlin 2>/dev/null || true
sudo find /opt -mindepth 2 -maxdepth 2 -type f \
  -name '.linuxcapable-kotlin-compiler' -printf '%h\n' | sort -V

The next block removes the marked archive versions, stable symlink, managed profile, and updater helper. Continue only after reviewing the preview and confirming that none of those compiler versions is still needed.

(
  set -euo pipefail
  marker='.linuxcapable-kotlin-compiler'
  helper='/usr/local/bin/update-kotlin-compiler'
  helper_marker='# Managed by the LinuxCapable Kotlin archive workflow'
  profile_file='/etc/profile.d/kotlin.sh'
  profile_content=$'# Managed by the LinuxCapable Kotlin archive workflow\nexport PATH="/opt/kotlin/bin:$PATH"'

  if sudo test -e "$helper" || sudo test -L "$helper"; then
    if ! sudo test -f "$helper" || sudo test -L "$helper" ||
       ! sudo grep -qxF "$helper_marker" "$helper"; then
      printf 'Refusing unmanaged helper: %s\n' "$helper" >&2
      exit 1
    fi
  fi

  if sudo test -e "$profile_file" || sudo test -L "$profile_file"; then
    if ! sudo test -f "$profile_file" || sudo test -L "$profile_file" ||
       [ "$(sudo cat "$profile_file")" != "$profile_content" ]; then
      printf 'Refusing unmanaged profile file: %s\n' "$profile_file" >&2
      exit 1
    fi
  fi

  if { [ -e /opt/kotlin ] || [ -L /opt/kotlin ]; } && [ ! -L /opt/kotlin ]; then
    printf '%s\n' '/opt/kotlin is not a symlink; refusing cleanup.' >&2
    exit 1
  fi

  if [ -L /opt/kotlin ]; then
    active_target="$(readlink -f /opt/kotlin 2>/dev/null || true)"
    if [[ ! "$active_target" =~ ^/opt/kotlin-[0-9]+\.[0-9]+\.[0-9]+$ ]] ||
       ! sudo test -f "$active_target/$marker"; then
      printf 'Refusing unmanaged /opt/kotlin target: %s\n' "$active_target" >&2
      exit 1
    fi
  fi

  mapfile -t managed_dirs < <(
    sudo find /opt -mindepth 2 -maxdepth 2 -type f \
      -name "$marker" -printf '%h\n' | sort -u
  )

  if [ "${#managed_dirs[@]}" -eq 0 ]; then
    printf '%s\n' 'No managed Kotlin archive directories were found.' >&2
    exit 1
  fi

  for managed_dir in "${managed_dirs[@]}"; do
    if [[ ! "$managed_dir" =~ ^/opt/kotlin-[0-9]+\.[0-9]+\.[0-9]+$ ]] ||
       ! sudo test -f "$managed_dir/$marker" ||
       ! sudo test -x "$managed_dir/bin/kotlinc"; then
      printf 'Refusing unexpected managed path: %s\n' "$managed_dir" >&2
      exit 1
    fi
  done

  if [ -L /opt/kotlin ]; then
    sudo rm -- /opt/kotlin
  fi
  if sudo test -e "$profile_file"; then
    sudo rm -- "$profile_file"
  fi
  if sudo test -e "$helper"; then
    sudo rm -- "$helper"
  fi

  for managed_dir in "${managed_dirs[@]}"; do
    sudo rm -rf -- "$managed_dir"
  done

  printf '%s\n' 'Removed the managed Kotlin archive installation and helper.'
)

Clear the shell command cache and check whether another installation method still provides Kotlin:

hash -r
command -v kotlinc || echo "kotlinc is no longer on PATH"
command -v update-kotlin-compiler || echo "The archive helper is removed"

Remove Kotlin Installed with Snap

Remove the Kotlin Snap and verify that it no longer appears in snapd’s installed list:

sudo snap remove --purge kotlin
snap list kotlin 2>/dev/null || echo "The Kotlin Snap is not installed"

Keep snapd installed when other Snap packages still use it. Remove the package manager separately only after checking snap list.

Conclusion

Once the sample JAR prints its message, the standalone Kotlin compiler and Fedora’s OpenJDK toolchain are working together. Keep the compiler current through its owning manager, then let Gradle, Maven, or your IDE pin the Kotlin plugin version for each real project.

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
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: