DGuard

SkinsRestorer: skins on an offline-mode server — setup, commands and proxies

On a server with online-mode=false players walk around in default skins: the server never gets signed textures from Mojang. The SkinsRestorer plugin brings back the skins of premium names and gives everyone a /skin command. This guide covers installing it on one server and behind Velocity or BungeeCord, the commands, permissions and settings — from the SkinsRestorer 15.12.6 documentation.

The DGuard team10 min read

In short: drop SkinsRestorer.jar into plugins/ and restart — the same jar runs on Paper, Spigot, Velocity and BungeeCord. A player with no chosen skin gets the skin of the Mojang account with the same name, and anyone can change it with /skin set <name> or /skin url "<PNG link>". Give regular players the skinsrestorer.player permission. On a network SkinsRestorer goes on the proxy and on every backend, and a MySQL database is only needed by plugins that call its API.

Why an offline-mode server has no skins

A Java Edition skin is a texture link in the player's profile, signed by Mojang's services. The client checks the signature, so nobody can slip in their own image. A server with online-mode=false doesn't verify accounts with Mojang and never receives a signed profile — the Minecraft Wiki names missing skins as a side effect of offline mode. Other players see such a player in one of the nine default skins. What else this mode changes and how to lock names behind a password is in offline-mode servers and auth plugins.

SkinsRestorer requests signed textures from Mojang itself (or from the MineSkin service for custom images) and puts them into the player's profile. On an offline-mode server it picks the skin at join in this order:

SituationThe skin others see
The player chose a skin with /skinThe chosen one — the choice is saved across joins
No choice, and a Mojang account with this name existsThat account's skin: a premium player on an offline server is back in their own skin
No choice, no account, default skins enabledA random one from storage.defaultSkins.list
A Bedrock player through FloodgateSkinsRestorer doesn't look for a Java skin — Floodgate shows the Bedrock skin
None of the aboveThe game's default skin
From the SkinsRestorer 15.12.6 source (PlayerStorageImpl). Default skins are off (storage.defaultSkins.enabled: false); with applyForPremium: true names with a Mojang account get them too

Installing on a single server

  1. 1

    Download the plugin

    Get SkinsRestorer.jar from Modrinth, Hangar or GitHub. Release 15.12.6 came out on 20 September 2026, and Modrinth lists versions from 1.8 to 26.3. It's free and licensed GPL-3.0.

  2. 2

    Stop the server and put the jar in plugins/

    Delete older SkinsRestorer jars but keep the data folder. Don't install plugins with /reload — the SkinsRestorer docs say so explicitly. The general routine is in how to install a plugin.

  3. 3

    Start it and read the console

    The plugin creates plugins/SkinsRestorer/config.yml. The defaults are fine for a first check.

  4. 4

    Grant permissions

    skinsrestorer.player gives players the ordinary commands and the skin menu. With LuckPerms it's the command below; groups are covered in LuckPerms.

  5. 5

    Test it

    Join with a regular non-OP account, run /skin set xknat and ask another player to look at you. Then rejoin: the skin must stay. Your own client may show the old skin for a moment — check through another player's eyes.

permissions for every player via LuckPerms
lp group default permission set skinsrestorer.player true

/skin commands and permissions

CommandWhat it doesPermission
/skin set <name> or /skin <name>The skin of the account with that nameskinsrestorer.command.set
/skin url "<link>" [classic|slim]A skin from a PNG link; slim is the thin-arm modelskinsrestorer.command.set.url
/skin clearDrop the choice: the account skin or a default comes backskinsrestorer.command.clear
/skin updateFetch a fresh copy of a copied skinskinsrestorer.command.update
/skin undo, /skin historyGo back to the previous skin, show the historyskinsrestorer.command.undo
/skins or /skin menuThe skin menu in an inventoryskinsrestorer.command.gui
/skin set <name> <player>Change another player's skinskinsrestorer.command.set.other
/sr createcustom <name> <player or link>A named server skin, e.g. for the menuskinsrestorer.admincommand.createcustom
/sr statusCheck the connection to Mojang's account servicesskinsrestorer.admincommand.status
/sr reloadReload config.ymlskinsrestorer.admincommand.reload
From the Commands and permissions page of the SkinsRestorer docs
  • Your own PNG without a premium account. The Upload page on the SkinsRestorer website takes a PNG up to 5 MB and returns a ready /skin url command — the player just pastes it in chat. Use the standard 64 × 64 skin template.
  • Cooldown. Skin changes are 30 seconds apart by default (commands.skinChangeCooldown), 5 seconds after an error. skinsrestorer.bypasscooldown skips it.
  • Staff permissions. skinsrestorer.admin includes the player commands and actions on other players, but not reload, dump and purgeolddata — grant those separately.
  • Don't test as OP. Operator status or broad wildcards hide mistakes in your groups: the docs recommend testing with a regular account.

SkinsRestorer behind Velocity and BungeeCord

On a network the proxy accepts players, stores their chosen skins and runs the /skin commands, while backends receive the finished profile. That's why SkinsRestorer goes on the proxy and on every backend — the same release everywhere.

  1. 1

    Set up player info forwarding

    Velocity: player-info-forwarding-mode = "modern" in velocity.toml, and on every Paper backend proxies.velocity.enabled: true with the same secret in config/paper-global.yml plus online-mode=false in server.properties. BungeeCord: ip_forward: true on the proxy and settings.bungeecord: true in the backends' spigot.yml. Step by step in Velocity setup.

  2. 2

    Put the jar on the proxy and all backends

    One release everywhere. Leave server.proxyMode.detection: AUTO on backends: with forwarding set up correctly the plugin detects the proxy itself.

  3. 3

    Grant permissions on the proxy

    The proxy runs the commands, so skinsrestorer.player must be granted in the proxy's permission plugin — for example LuckPerms for Velocity. A permission granted only on a backend won't unlock the command.

  4. 4

    Test a server switch

    Join through the proxy address, change your skin and move to another backend. If the skin shows on one server only, compare its forwarding settings with a working one.

When you need MySQL

By default data lives in files (database.type: FILE), and that's enough for ordinary skins on a network: the docs specifically say several backends are no reason to add a database. MySQL or PostgreSQL is needed when a plugin on a backend calls the SkinsRestorer API — then the proxy and those backends connect to one database with the same table prefix. More on databases for plugins in MySQL for plugins.

plugins/SkinsRestorer/config.yml — excerpt, then restart
database:
  type: MYSQL
  host: "127.0.0.1"
  port: 3306
  database: "skinsrestorer"
  username: "skinsrestorer"
  password: "database-password"
  tablePrefix: "sr_"
  • Changing database.type doesn't move existing file records into the database — plan the transfer separately and take a backup first.
  • The storage type, connection and proxy detection only apply after a restart, not after /sr reload.
  • If backends don't need the API, set server.proxyMode.api: false on them — skins from the proxy keep working as before.

Settings worth knowing

KeyDefaultWhy change it
storage.defaultSkins.enabledfalseTurn on your own default skins for names without a Mojang account
commands.disabledSkins.enabledfalseBlock skins from commands.disabledSkins.list — for example your staff's names
commands.restrictSkinUrls.enabledfalseAllow /skin url only for whitelisted links
commands.skinChangeCooldown30Seconds between skin changes; 0 disables the cooldown
api.elyByEnabledfalseUse Ely.by account skins instead of Mojang's
messages.localeenMessage language; with messages.perIssuerLocale: true a player sees their client's language when a translation exists
Keys and defaults from the SkinsRestorer 15.12.6 configuration reference

Paid skins. With commands.perSkinPermissions on, every skin needs a skinsrestorer.skin.<name> permission. The plugin only turns this on if perSkinPermissionsConsent contains the consent to its rules: players must not pay to use their own skin, you must not swap their skin for a default one to force a payment, and you may charge for custom skins you provide. How to sell perks within Mojang's rules is covered in monetization and the EULA.

Skins and the anticheat

A skin is only a texture. A standing player's hitbox in Java Edition is 0.6 × 1.8 blocks whatever skin or arm model they pick: a slim Alex skin doesn't make anyone smaller, and only the Hitbox cheat enlarges the target. DGuard — the best anticheat for a modern Minecraft server — checks behavior and packets, not the account or the looks, so on an offline-mode server it works exactly as on a premium one: a new name or someone else's skin doesn't make a cheater invisible.

DGuard is a Paper and Leaf plugin for 1.21–26.3; it works behind Velocity and BungeeCord and makes exceptions for Bedrock players coming through Floodgate — the same network layout as SkinsRestorer. Up to 30 players online DGuard is free, with the same protection as the paid plans.

FAQ

How do I get skins on an offline-mode (cracked) Minecraft server?

Install the SkinsRestorer plugin: SkinsRestorer.jar into plugins/ and restart. Players whose name matches a premium account get that skin automatically; everyone else picks one with /skin set <name> or /skin url "<link>".

How do I change my skin with SkinsRestorer?

Use /skin set <name> for the skin of the account with that name, or /skin url "<PNG link>" slim for your own PNG with thin arms. /skin undo brings back the previous one and /skin clear drops your choice.

Why doesn't SkinsRestorer change my skin?

If the command is denied, the player lacks skinsrestorer.player or the specific node, or on a network the permission wasn't granted on the proxy. If the command succeeds but nothing changes, ask another player to look: a launcher or skin mod can override skins on one client only. On a network, check player info forwarding and SkinsRestorer on every backend.

Does SkinsRestorer need MySQL on a Velocity network?

Not for ordinary skins: the proxy keeps the choices in files and passes skins to the backends itself. MySQL or PostgreSQL is only needed when plugins on the backends call the SkinsRestorer API.

Does SkinsRestorer work on an online-mode server?

Yes, it supports both online-mode=true and online-mode=false. Don't turn off authentication for skins: on a premium server SkinsRestorer simply lets players change their skin with commands.

Sources

All sections

Run the best anticheat for modern Minecraft

DGuard catches all 47 kinds of cheats in our comparison — the closest rival, Intave, has 27. Full protection on every plan, free up to 30 players online.