# SkinsRestorer documentation URL: /docs SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Install SkinsRestorer, change a skin, or solve a server problem. SkinsRestorer lets players change their Minecraft Java Edition skin on a server. Server owners can restore account skins, offer custom skins, and manage who can change them. ## What do you want to do? [#what-do-you-want-to-do] [Install SkinsRestorer](/docs/installation) Choose your server or proxy and check your first skin. [Change a skin](/docs/features/change-skin) Use a player name, upload a PNG, or restore your account skin. [Fix a problem](/docs/troubleshooting) Start with the symptom and collect the right diagnostics. [Build an integration](/docs/development) Fetch, save, and apply skins through the Java API. ## Find the right guide [#find-the-right-guide] * **New server owner:** Start with [installation](/docs/installation). A proxy network needs SkinsRestorer on the proxy and every backend. * **Player:** Read [change or reset your skin](/docs/features/change-skin). Your server must provide SkinsRestorer and permission to use it. * **Administrator:** Configure [player access](/docs/configuration/player-access), [default skins](/docs/configuration/default-skins), or [shared storage](/docs/configuration/database). * **Developer:** Start with the [first plugin tutorial](/docs/development/first-plugin), then read about [persistent and temporary changes](/docs/development/storage). Exact command syntax and configuration keys live in the [reference](/docs/reference). The [skin lifecycle](/docs/development/inner-workings) explains why a visible skin and a saved selection can differ. ## Version and support [#version-and-support] These guides target **SkinsRestorer 15.12.6**. Each page shows its applicable platform and review date. Minecraft and Java requirements depend on the platform and download. Use the [compatibility guide](/docs/installation/requirements) before you install a mod or update a server. For a support request, collect a [diagnostic report and recent log](/docs/troubleshooting/debugging). # Understand SkinsRestorer URL: /docs/concepts SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Learn how skin data, caching, and proxy ownership fit together. These pages explain the model behind the setup guides. They help when a visible skin and a saved selection disagree. * [How a skin reaches a player](/docs/development/inner-workings). * [Signed skin properties](/docs/concepts/skin-properties). * [Proxy ownership and backend storage](/docs/concepts/proxy). * [Cape behavior and limits](/docs/features/capes). For steps to perform a task, use [installation](/docs/installation), [server management](/docs/configuration), or [the API guides](/docs/development). # Who owns skins on a proxy network? URL: /docs/concepts/proxy SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Separate proxy selections, backend forwarding, and backend API access. The public proxy receives the player connection. It owns ordinary SkinsRestorer commands and selected skins. Each backend receives the forwarded profile. ## Normal forwarding [#normal-forwarding] SkinsRestorer runs on the proxy and every backend. The platform forwards identity and profile information. Backend SkinsRestorer detects proxy mode and participates in the skin application path. The proxy can use file storage. The backends do not need shared SQL storage solely to display forwarded skins. ## Backend API consumers [#backend-api-consumers] A plugin on a backend can ask for stored selections or change them through the Java API. That requires the same MySQL or PostgreSQL storage as the proxy. `server.proxyMode.api` controls backend API availability. It does not turn profile forwarding into a database operation. ## Permissions and administration [#permissions-and-administration] Grant player command permissions where the commands run, usually the proxy. Use the proxy for storage administration. Proxy-mode backends expose local status and dump diagnostics. A backend warning can concern API availability while visible forwarded skins still work. ## Why mismatches happen [#why-mismatches-happen] Incorrect UUID forwarding can make the same player appear as different records. Independent backend commands can also create competing selections. A shared database does not correct identity forwarding. First configure [Velocity](/docs/installation/velocity) or [BungeeCord](/docs/installation/bungeecord). Then configure [backend API access](/docs/development/proxy-api) if an integration needs it. # Signed skin properties URL: /docs/concepts/skin-properties SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Understand texture URLs, models, signatures, and cape data. Minecraft profiles carry a `textures` property. Its value is Base64-encoded JSON. Its signature authenticates that value. ## What the property contains [#what-the-property-contains] The decoded data can include a skin URL, model metadata, and a cape URL. A skin texture URL identifies an image on Minecraft's texture service. A texture hash is the identifier at the end of that URL. It is not a player UUID or a saved SkinsRestorer custom name. ## Why a PNG needs generation [#why-a-png-needs-generation] A local PNG does not contain a signed profile property. A generation service uploads the image and returns the property that a server can apply. Changing the encoded value without a matching signature makes the signature invalid. Keep the value and signature together when storing or transferring a property. ## Model and cape [#model-and-cape] Classic and slim use different arm layouts. The image and model metadata must agree. A cape belongs to the complete profile property. Copying an account property can copy its equipped cape. The website can also generate supported cape combinations through its cape-aware route. Showing that property on a server does not transfer account ownership of a cape. ## Next [#next] [Upload an image](/docs/features/skin-upload), or [fetch and apply a property through the API](/docs/development/storage). # Update SkinsRestorer URL: /docs/configuration/auto-update SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Choose automatic downloads or a controlled manual update. SkinsRestorer checks for updates at startup and periodically afterward. The repeating interval is randomized between 60 and 240 minutes. Update checks and automatic downloads are different actions. Download behavior depends on the platform. ## Manual update [#manual-update] 1. Read the target release notes and [platform requirements](/docs/installation/requirements). 2. [Back up the active storage](/docs/configuration/backups). 3. Stop the affected instances. 4. Replace the old JAR with the matching release artifact. 5. Remove duplicate SkinsRestorer JARs. 6. Start the instances. 7. Read the startup logs. 8. Complete the [first skin check](/docs/installation/quick-start). On a network, update the proxy and backends together. A Fabric or NeoForge update also needs a matching Minecraft and loader version. ## Disable automatic downloads [#disable-automatic-downloads] Create an empty `noautoupdate.txt` file in the SkinsRestorer data directory. The older `noupdate.txt` filename is also recognized by this release. Restart after changing the file. This controls the updater's download behavior. Plan manual updates instead of relying on a disabled downloader. `advanced.noConnections` also stops update connections, but it disables skin lookups and URL generation too. Do not use it only to manage updates. ## If the update fails [#if-the-update-fails] Restore the backup and compatible previous artifact. Keep the failed startup log for diagnosis. Do not delete storage to make an incompatible release start. Read [support diagnostics](/docs/troubleshooting/debugging) if you need help with an update error. # Back up and restore skin data URL: /docs/configuration/backups SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Preserve selections, custom skins, and configuration before an update. A backup must match the storage backend in use. The configuration file alone does not contain player selections or custom skin data. ## File storage [#file-storage] 1. Stop the instance that writes skin data. 2. Copy its complete SkinsRestorer data directory to a separate location. 3. Record the plugin or mod version with the backup. 4. Start the instance again. Keep the configuration, locales, and all storage subdirectories together. On a proxy network, the proxy usually owns the selections. ## SQL storage [#sql-storage] Use your database host's consistent backup or dump procedure. Back up the SkinsRestorer tables and the configuration of every connected instance. A copy of `config.yml` cannot restore SQL records. Do not copy live database files without a database-specific backup procedure. ## Restore [#restore] 1. Stop all instances that write to the affected storage. 2. Preserve the current data as a separate recovery copy. 3. Restore the saved data and matching configuration. 4. Start one instance and read its startup log. 5. Check a custom skin and a player's saved selection. 6. Start the remaining instances. Use a compatible release for the restored data. Older releases can fail to read newer formats. ## Remove old data [#remove-old-data] `/sr purgeolddata ` removes old skin data. `/sr drop player ` removes a player record. `/sr drop skin ` removes stored skin data. Back up before these operations. They are administrative maintenance commands, not fixes for every skin problem. Continue with [updates](/docs/configuration/auto-update) or [shared storage](/docs/configuration/database). # Commands and permissions URL: /docs/configuration/commands-permissions SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact command forms, aliases, permission nodes, and built-in groups. `` is required. `[argument]` is optional. `a|b` lists aliases. Keep URLs and multi-word quoted arguments inside quotation marks. Run player-only commands in game. Console commands omit the leading slash. Availability depends on the platform and proxy mode. ## Commands [#commands] ### Player commands [#player-commands] | Syntax | Permission | | ------------------------------------------------------- | --------------------------------------- | | `/skin` | `skinsrestorer.command` | | `/skin help [query]` | `skinsrestorer.command` | | `/skin ` | `skinsrestorer.command.set` | | `/skin ` | `skinsrestorer.command.set.other` | | `/skin clear\|reset` | `skinsrestorer.command.clear` | | `/skin clear\|reset ` | `skinsrestorer.command.clear.other` | | `/skin random` | `skinsrestorer.command.random` | | `/skin random ` | `skinsrestorer.command.random.other` | | `/skin search ` | `skinsrestorer.command.search` | | `/skin edit` | `skinsrestorer.command.edit` | | `/skin upload` | `skinsrestorer.command.set.url` | | `/skin update\|refresh` | `skinsrestorer.command.update` | | `/skin update\|refresh ` | `skinsrestorer.command.update.other` | | `/skin set\|select ` | `skinsrestorer.command.set` | | `/skin set\|select ` | `skinsrestorer.command.set.other` | | `/skin set\|select ` | `skinsrestorer.command.set.other` | | `/skin url [skinVariant]` | `skinsrestorer.command.set.url` | | `/skin undo\|revert` | `skinsrestorer.command.undo` | | `/skin undo\|revert ` | `skinsrestorer.command.undo.other` | | `/skin history` | `skinsrestorer.command.undo` | | `/skin history ` | `skinsrestorer.command.undo.other` | | `/skin favourite` | `skinsrestorer.command.favourite` | | `/skin favourite ` | `skinsrestorer.command.favourite.other` | | `/skin favourites` | `skinsrestorer.command.favourite` | | `/skin favourites ` | `skinsrestorer.command.favourite.other` | | `/skin menu\|gui` | `skinsrestorer.command.gui` | | `/skin notification ignore-cracked-client` | No explicit command permission | ### Menu command [#menu-command] | Syntax | Permission | | -------- | --------------------------- | | `/skins` | `skinsrestorer.command.gui` | ### Skull commands [#skull-commands] | Syntax | Permission | | ------------------------------------------------------ | ----------------------------------------------- | | `/skull` | `skinsrestorer.command.skull` | | `/skull help [query]` | `skinsrestorer.command.skull` | | `/skull ` | `skinsrestorer.admincommand.skull.get` | | `/skull ` | `skinsrestorer.admincommand.skull.get.other` | | `/skull random` | `skinsrestorer.admincommand.skull.random` | | `/skull random ` | `skinsrestorer.admincommand.skull.random.other` | | `/skull get\|give ` | `skinsrestorer.admincommand.skull.get` | | `/skull get\|give ` | `skinsrestorer.admincommand.skull.get.other` | | `/skull get\|give ` | `skinsrestorer.admincommand.skull.get.other` | | `/skull url [skinVariant]` | `skinsrestorer.admincommand.skull.get.url` | ### Admin commands [#admin-commands] | Syntax | Permission | | ------------------------------------------------------- | ----------------------------------------- | | `/sr` | `skinsrestorer.admincommand` | | `/sr help [query]` | `skinsrestorer.admincommand` | | `/sr reload` | `skinsrestorer.admincommand.reload` | | `/sr docs permissions` | `skinsrestorer.admincommand` | | `/sr status` | `skinsrestorer.admincommand.status` | | `/sr drop\|remove player ` | `skinsrestorer.admincommand.drop` | | `/sr drop\|remove skin ` | `skinsrestorer.admincommand.drop` | | `/sr info\|props\|lookup player ` | `skinsrestorer.admincommand.info` | | `/sr info\|props\|lookup skin ` | `skinsrestorer.admincommand.info` | | `/sr applyskin ` | `skinsrestorer.admincommand.applyskin` | | `/sr createcustom ` | `skinsrestorer.admincommand.createcustom` | | `/sr createcustom ` | `skinsrestorer.admincommand.createcustom` | | `/sr setcustomname ` | `skinsrestorer.admincommand.createcustom` | | `/sr purgeolddata ` | `skinsrestorer.admincommand.purgeolddata` | | `/sr dump` | `skinsrestorer.admincommand.dump` | ## Special permissions [#special-permissions] | Permission | Purpose | | ------------------------------ | ---------------------------------------------------------------------------- | | `skinsrestorer.player` | Built-in player group: ordinary self-service commands and the menu | | `skinsrestorer.command.*` | Alternate grant for the built-in player group | | `skinsrestorer.admin` | Built-in admin group, including the player group and other-player operations | | `skinsrestorer.admincommand.*` | Alternate grant for the built-in admin group | | `skinsrestorer.bypasscooldown` | Bypass command cooldowns | | `skinsrestorer.bypassdisabled` | Bypass blocked skin names | | `skinsrestorer.ownskin` | Select your own account name with per-skin permissions enabled | | `skinsrestorer.skin.` | Select an individual permitted skin | The built-in admin group omits `reload`, `dump`, and `purgeolddata`. Grant those nodes explicitly when needed. A permission plugin can interpret wildcards differently. Commands can require their parent command access too. The root nodes are `skinsrestorer.command`, `skinsrestorer.admincommand`, and `skinsrestorer.command.skull`. Use [player access](/docs/configuration/player-access) to configure groups. Use [skin restrictions](/docs/configuration/restrict-skins) for per-skin access and required consent. ## Target selectors and administrative behavior [#target-selectors-and-administrative-behavior] A `` identifies the target player or players through the platform's selector parser. Use an explicit player name first. Selector support can depend on the platform. `/skin set ` changes a target's saved selection. `/sr applyskin ` reapplies the skin resolved for the target. There are no `setskinall` or `applyskinall` commands in this release. `/sr createcustom` stores a named skin. `/sr setcustomname` changes its display label and uses the same permission. `drop` and `purgeolddata` remove stored data, so [back up first](/docs/configuration/backups). `/skin favourite` toggles the current selection in favorites. `history` uses the `undo` permission. `search`, `edit`, and `upload` provide browser links rather than saving an edited image themselves. `/sr status` checks account services. `/sr dump` uploads a diagnostic report. Read [diagnostic collection](/docs/troubleshooting/debugging) for what each includes. ## Proxy mode [#proxy-mode] Run normal player commands and storage administration through the proxy. Proxy-mode backends provide local `/sr status` and `/sr dump`. Other commands can be unavailable there by design. ## Cooldowns [#cooldowns] Skin changes and skull requests each use a 30-second cooldown by default. Their error cooldowns default to 5 seconds. `skinsrestorer.bypasscooldown` bypasses these cooldowns. Use [command configuration](/docs/reference/commands) to change the durations. ## Restricting skin access [#restricting-skin-access] Use [player access](/docs/configuration/player-access) for permission groups. Use [skin restrictions](/docs/configuration/restrict-skins) for blocked names, URL prefixes, and per-skin permissions. ## Create a support report [#create-a-support-report] Use [diagnostic collection](/docs/troubleshooting/debugging) for `/sr dump`, debug logs, and a reproducible support report. ## Source [#source] The syntax and nodes above come from the [15.12.6 command definitions](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/shared/src/main/java/net/skinsrestorer/shared/commands) and [permission groups](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/subjects/permissions/PermissionGroup.java). # Configure shared storage URL: /docs/configuration/database SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Choose file storage, MySQL, or PostgreSQL and connect a shared backend API. File storage is the default. Ordinary proxy-managed skins work without a shared database. A backend API integration in proxy mode needs shared MySQL or PostgreSQL storage. ## Before you switch [#before-you-switch] Back up the existing data and configuration. Create a database and a dedicated database user. Allow access from each server that uses it. Changing `database.type` selects another storage backend. It does **not** copy existing file records into SQL. Plan and check any data transfer separately before you replace production storage. ## MySQL example [#mysql-example] Stop each affected instance, then edit its existing database section: ```yaml title="config.yml (SkinsRestorer excerpt)" database: type: MYSQL host: "127.0.0.1" port: 3306 database: "skinsrestorer" username: "skinsrestorer" password: "REPLACE_WITH_DATABASE_PASSWORD" maxPoolSize: 10 tablePrefix: "sr_" connectionOptions: "sslMode=trust&serverTimezone=UTC" ``` ## PostgreSQL example [#postgresql-example] ```yaml title="config.yml (SkinsRestorer excerpt)" database: type: POSTGRESQL host: "127.0.0.1" port: 5432 database: "skinsrestorer" username: "skinsrestorer" password: "REPLACE_WITH_DATABASE_PASSWORD" maxPoolSize: 10 tablePrefix: "sr_" connectionOptions: "" ``` Choose connection options for your driver and host's TLS requirements. Do not carry MySQL options into PostgreSQL without checking their meaning. ## Share storage on a network [#share-storage-on-a-network] Use the same type, database, and table prefix on the proxy and API-enabled backends. Each instance must have database access. Keep `server.proxyMode.api: true` on backends that call the API. For backends without API consumers, you can disable it and keep normal proxy skin forwarding. Start the instances and inspect their database initialization logs. Change a test player's skin through the proxy, then resolve it through the backend integration. ## If the connection fails [#if-the-connection-fails] Check host resolution, port access, credentials, permissions to create tables, and driver options. `/sr status` does not prove that the database works. The old `database.enabled` key belongs to earlier configuration. This release migrates older configuration, but new examples use `database.type`. Read [backup and recovery](/docs/configuration/backups) before another storage change. # Set default skins URL: /docs/configuration/default-skins SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Choose the fallback skin for players without a saved selection. Default skins apply during skin resolution. An explicit player selection takes priority over the fallback list. ## Configure one default [#configure-one-default] 1. [Create a custom skin](/docs/features/custom-skins) named `lobby`. 2. Edit the existing `storage` section. ```yaml title="config.yml (SkinsRestorer excerpt)" storage: defaultSkins: enabled: true applyForPremium: false list: - "lobby" ``` 3. Run `/sr reload` on the server or proxy that owns storage. 4. Run `/skin clear` with a test player. 5. Reconnect and check the resolved skin. With `applyForPremium: false`, players with an account skin keep that skin. Set it to `true` if the default must also apply to those players without a saved selection. ## Use several defaults [#use-several-defaults] Add more names to `storage.defaultSkins.list`. SkinsRestorer chooses a list entry at random. `""` requests a random recommended skin. Recommended skins need `api.fetchRecommendedSkins`. If recommendations are unavailable, a random entry cannot provide one. ## If the default does not appear [#if-the-default-does-not-appear] Check that the custom name exists with `/sr info skin lobby`. Remove the test player's saved selection with `/skin clear`. Then inspect proxy mode and `advanced.disableOnJoinSkins`. For priorities and caching, read [the skin lifecycle](/docs/development/inner-workings). # Manage your server URL: /docs/configuration SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Control player access, default skins, storage, messages, and updates. Start with the behavior you want to change. The guides use configuration excerpts, not full replacement files. ## Common tasks [#common-tasks] * [Grant player access](/docs/configuration/player-access). * [Set default skins](/docs/configuration/default-skins). * [Create named custom skins](/docs/features/custom-skins). * [Restrict skins and URLs](/docs/configuration/restrict-skins). * [Configure the skin menu](/docs/configuration/skin-menu). * [Change messages and translations](/docs/configuration/locale-translations). * [Configure shared SQL storage](/docs/configuration/database). * [Update SkinsRestorer](/docs/configuration/auto-update). * [Back up skin data](/docs/configuration/backups). ## Change configuration safely [#change-configuration-safely] 1. Back up the active configuration file. 2. Edit the existing section in `config.yml`. 3. Keep YAML indentation consistent. 4. Apply the change with `/sr reload` or a restart, as the guide specifies. 5. Repeat the task that the configuration controls. Do not paste a second copy of the same top-level section. A YAML parser can replace one copy silently. On Bukkit servers, the file is `plugins/SkinsRestorer/config.yml`. On other platforms, use the data directory reported at startup. The [configuration reference](/docs/configuration/options) lists exact keys and defaults. Command registration, storage changes, and platform forwarding need a restart. # Change messages and translations URL: /docs/configuration/locale-translations SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Select a locale and customize translated messages. SkinsRestorer uses locale files and MiniMessage text. Player messages and console messages have separate locale configuration. ## Select the locale [#select-the-locale] Edit the existing `messages` section: ```yaml title="config.yml (SkinsRestorer excerpt)" messages: locale: "en" consoleLocale: "en" perIssuerLocale: false disablePrefix: false dateFormat: "dd MMMM yyyy" ``` With `perIssuerLocale: true`, a player's client locale can take priority over the configured default. Use `false` if all players must receive the same language. Run `/sr reload`, then check a player message and the console. Use a locale code supported by the installed release. ## Customize messages [#customize-messages] 1. Back up the `locales` directory inside the SkinsRestorer data folder. 2. Open the locale file for the language in use. 3. Change the message text without removing its placeholders. 4. Keep the JSON valid. 5. Run `/sr reload`. 6. Trigger the changed message with a test account. The bundled default file is `locales/locale.json`. Inspect the generated directory for the exact filenames of other languages. MiniMessage tags control formatting. A placeholder such as `` supplies data from the command. Removing it can make a message less useful. ## Custom command help [#custom-command-help] `commands.customHelp.enabled` and `commands.customHelp.message` replace the configured `/skin` help text. They do not replace every command error or subcommand message. ## Contribute a translation [#contribute-a-translation] Use the [SkinsRestorer translation project](https://translate.skinsrestorer.net). Keep technical names and placeholders unchanged. For configuration defaults, read [messages and diagnostics](/docs/reference/messages). # Configuration reference URL: /docs/configuration/options SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Find exact configuration keys by section and avoid obsolete examples. This reference covers every declared configuration property in SkinsRestorer 15.12.6. It separates lookup tables from [server management procedures](/docs/configuration). ## File structure [#file-structure] Edit the existing sections in the active `config.yml`. On Bukkit, the file is `plugins/SkinsRestorer/config.yml`. ## Storage settings [#storage-settings] [Default skins and cache durations](/docs/reference/storage) control fallback selection and account lookup caching. ## Command settings [#command-settings] [Command behavior](/docs/reference/commands) covers cooldowns, restrictions, history, favorites, and command registration. ## Login settings [#login-settings] [Login behavior](/docs/reference/server) controls canceled logins, online-mode selection application, and client warnings. ## Server settings (Backend only) [#server-settings-backend-only] [Server behavior](/docs/reference/server) covers refresh, mounts, sound, and backend proxy detection. Server-specific values do not configure the proxy itself. ## Proxy settings (Proxy only) [#proxy-settings-proxy-only] [Proxy command restrictions](/docs/reference/server) allow or block commands by backend name. ## API settings [#api-settings] [External services](/docs/reference/services) covers MineSkin keys, recommendations, batching, and Ely.by. ## GUI settings [#gui-settings] [Menu categories and entries](/docs/reference/gui) lists the exact category keys and defaults. ## Advanced settings [#advanced-settings] [Advanced behavior](/docs/reference/advanced) changes join application, refresh workarounds, and external connections. ## Debug settings [#debug-settings] [Messages and diagnostics](/docs/reference/messages) covers `dev.debug`, locales, prefixes, and dates. ## Correct common outdated keys [#correct-common-outdated-keys] * Use `database.type: MYSQL` or `POSTGRESQL` for new SQL configuration. Earlier `database.enabled` configuration is migrated by the plugin. * `commands.perSkinPermissions` is a boolean, not a section with `enabled` and `list`. * Use `api.mineskinAPIKey` and `api.mineskinSecretSkins` with that exact capitalization. * Use `gui.custom` and `gui.custom.onlyShowList`, rather than `customSkins` and `onlyList`. * Use `proxy.notAllowedCommandServers.ifNoServerBlockCommand`. * Mount refresh keys include `OnSkinUpdate`, such as `server.dismountPlayerOnSkinUpdate`. ## Apply an excerpt [#apply-an-excerpt] Edit the matching section in the existing file. Do not paste duplicate top-level keys. Restart after storage, proxy detection, or command registration changes. For permissions, use [the command reference](/docs/configuration/commands-permissions). For release verification and maintenance, use [the documentation sources](/docs/reference/documentation). # Grant player access URL: /docs/configuration/player-access SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Give players and staff the command permissions they need. Configure permissions on the platform that owns the command. On a proxy network, ordinary skin commands run through the proxy. ## Allow normal player commands [#allow-normal-player-commands] Grant `skinsrestorer.player` to the player group in your permission plugin. This group covers ordinary skin changes, URLs, history, favorites, search, edit, and the menu. For LuckPerms, a typical grant is: ```text /lp group default permission set skinsrestorer.player true ``` Use the permission manager installed on your proxy or server. This example is a LuckPerms command, not a SkinsRestorer command. Some platforms provide player permissions by default. `commands.forceDefaultPermissions` controls fallback defaults on platforms without that support. An explicit denial can override a grant. ## Limit access to specific commands [#limit-access-to-specific-commands] Use individual nodes from the [command reference](/docs/configuration/commands-permissions). For example, a URL change needs `skinsrestorer.command.set.url` and the relevant command access. If a broad group already grants URL access, adding a narrower positive permission does not remove it. Remove the broad grant or explicitly deny the unwanted node. ## Grant staff commands [#grant-staff-commands] Grant only the nodes needed for the staff task. `skinsrestorer.admin` includes player commands, other-player operations, and several administrative actions. The built-in admin group does **not** list `reload`, `dump`, or `purgeolddata` in 15.12.6. Grant those operational permissions explicitly if staff need them. A permission plugin's wildcard behavior can differ from SkinsRestorer's groups. ## Check [#check] 1. Join with a regular player account. 2. Run `/skin set xknat`. 3. Try a staff-only operation with that account. 4. Check the permission manager's effective permissions if results differ. Do not use an operator account as the only permission check. For denied commands, use [permission troubleshooting](/docs/troubleshooting/permissions). # Restrict skins and URLs URL: /docs/configuration/restrict-skins SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Control allowed URLs, blocked skin names, and per-skin permissions. These restrictions control skin selection. They do not replace your permission manager or the server's authentication policy. ## Restrict URL sources [#restrict-url-sources] Edit the existing `commands` section: ```yaml title="config.yml (SkinsRestorer excerpt)" commands: restrictSkinUrls: enabled: true list: - "https://textures.minecraft.net/" - "https://minesk.in/" - "skinsrestorer-axolotl://" ``` Run `/sr reload`. Then try a permitted texture URL and a URL outside the list. Generated commands can use a texture URL, a MineSkin URL, or an opaque Axolotl value. Keep only the prefixes your players need. URL restrictions use literal prefix matching. Include the slash after the host to avoid matching similarly named hosts. Keep `skinsrestorer.command.set.url` only for players who need URL changes. ## Block named skins [#block-named-skins] ```yaml title="config.yml (SkinsRestorer excerpt)" commands: disabledSkins: enabled: true list: - "owner" ``` Players with `skinsrestorer.bypassdisabled` bypass this restriction. Do not grant that bypass to the normal player group. ## Require permission for each skin [#require-permission-for-each-skin] The release requires consent to these rules: * Players must not pay to use their own skin. * Do not replace player skins with Steve to force payment. * You can charge for custom skins that you provide. If you accept those rules, use: ```yaml title="config.yml (SkinsRestorer excerpt)" commands: perSkinPermissions: true perSkinPermissionsConsent: "I will follow the rules" ``` `perSkinPermissions` is a boolean. There is no `perSkinPermissions.enabled` or configured permission list. Grant `skinsrestorer.skin.` for an allowed skin. Grant `skinsrestorer.ownskin` so players can select their own account name. Keep ordinary command permissions too. ## Check [#check] After `/sr reload`, check allowed and denied choices with a non-operator account. If both fail, inspect [effective permissions](/docs/troubleshooting/permissions) and the console for consent errors. # Configure the skin menu URL: /docs/configuration/skin-menu SkinsRestorer: 15.12.6 Applies to: Platforms with inventory GUI support Reviewed: 2026-10-01 Choose categories and visible entries in /skins. The menu separates named custom skins, cached player skins, and recommended skins. Its configuration uses `gui.custom`, `gui.players`, and `gui.recommendations`. ## Show a curated custom list [#show-a-curated-custom-list] 1. [Create the custom skins](/docs/features/custom-skins) that you want to offer. 2. Edit the existing `gui` section. ```yaml title="config.yml (SkinsRestorer excerpt)" gui: custom: enabled: true index: 0 onlyShowList: true list: - "lobby" - "builder" players: enabled: false recommendations: enabled: false ``` 3. Run `/sr reload`. 4. Open `/skins` with a regular player account. 5. Select each listed skin and check the result. `onlyShowList` filters visible entries. It does not grant permission to use a skin. [Per-skin permissions](/docs/configuration/restrict-skins) still apply. ## Show player or recommended skins [#show-player-or-recommended-skins] Set the category's `enabled` value to `true`. Its `index` controls its position relative to the other categories. Smaller values appear earlier. A curated `gui.players.list` uses player UUIDs. A curated recommendations list uses recommendation IDs. Neither list uses custom skin names. Recommended entries also require `api.fetchRecommendedSkins: true`. ## If entries are missing [#if-entries-are-missing] Check that the category is enabled and that each listed identifier exists. A locked entry can mean missing per-skin permission. Check [the GUI reference](/docs/reference/gui) for defaults and exact keys. # Dependencies and API lifecycle URL: /docs/development/api SkinsRestorer: 15.12.6 Applies to: Java plugins using API 15.12.6 Reviewed: 2026-10-01 Add the public API without bundling it and initialize after SkinsRestorer. Use `net.skinsrestorer:skinsrestorer-api:15.12.6` as a compile-time dependency. The installed SkinsRestorer plugin supplies it at runtime. ## Add to your build file [#add-to-your-build-file] The [first plugin tutorial](/docs/development/first-plugin) contains a complete Maven project. For Gradle, use: ```kotlin title="build.gradle.kts (excerpt)" repositories { maven("https://repo.codemc.org/repository/maven-public/") } dependencies { compileOnly("net.skinsrestorer:skinsrestorer-api:15.12.6") } ``` ```groovy title="build.gradle (excerpt)" repositories { maven { url = 'https://repo.codemc.org/repository/maven-public/' } } dependencies { compileOnly 'net.skinsrestorer:skinsrestorer-api:15.12.6' } ``` Do not shade or relocate the API. Do not import `net.skinsrestorer.shared` or platform implementation classes. ## Add SkinsRestorer as a dependency [#add-skinsrestorer-as-a-dependency] For a Bukkit plugin that requires SkinsRestorer: ```yaml title="plugin.yml (dependency excerpt)" depend: [SkinsRestorer] ``` For an optional Bukkit integration, use `softdepend: [SkinsRestorer]`. Check that SkinsRestorer is enabled before loading API-dependent integration classes. BungeeCord uses `depends` or `softDepends` in `bungee.yml`. Velocity declares dependencies with `@Dependency(id = "skinsrestorer", optional = true)` inside the plugin annotation. Remove `optional = true` for a required dependency. ## Getting the API instance [#getting-the-api-instance] Call `SkinsRestorerProvider.get()` after SkinsRestorer initializes, usually in your enable callback. Do not call it from a static initializer or plugin constructor. An installed JAR does not prove that the API initialized. The provider throws `IllegalStateException` when unavailable. Backend proxy API mode can require [shared SQL storage](/docs/development/proxy-api). ## Checking API version compatibility [#checking-api-version-compatibility] `VersionProvider.isCompatibleWith("15")` checks major-version compatibility. It is not a test for “version 15 or newer.” Pin the dependency version used by your build. Test your integration against the installed release before you change its dependency. ## Error handling [#error-handling] Skin lookup and generation can perform blocking requests. Storage can also perform database I/O. Keep this work outside the platform's main or entity thread. Schedule your own player operations with the platform's supported scheduler. The [complete Bukkit example](/docs/development/first-plugin) shows that boundary. A Bukkit scheduler example does not automatically work on Folia, Velocity, or BungeeCord. Read [storage operations](/docs/development/storage) before choosing an apply method. ## Code examples [#code-examples] Start with [the complete plugin tutorial](/docs/development/first-plugin). Then choose [persistent or temporary changes](/docs/development/storage) for your integration. ## Use the API on a proxy network [#use-the-api-on-a-proxy-network] Follow [proxy API setup](/docs/development/proxy-api) before requesting the provider on a backend. # Build your first skin plugin URL: /docs/development/first-plugin SkinsRestorer: 15.12.6 Applies to: Paper / Spigot, Bukkit scheduling, API 15.12.6 Reviewed: 2026-10-01 Compile a Bukkit plugin that saves and applies a player-name skin. This tutorial creates `/exampleskin `. It fetches the skin outside the main thread, saves the selection, and applies the resolved property. ## Before you start [#before-you-start] You need Maven, JDK 21 or newer, and a standalone Paper or Spigot test server with SkinsRestorer 15.12.6. The example uses Bukkit scheduling and does **not** declare Folia support. A proxy backend also needs [backend API configuration](/docs/development/proxy-api). ## Create the project [#create-the-project] Create these files in an empty directory: ```text pom.xml src/main/resources/plugin.yml src/main/java/example/ExampleSkinPlugin.java ``` ### Maven build [#maven-build] ```xml title="pom.xml" 4.0.0 example example-skin 1.0.0 21 UTF-8 spigot https://hub.spigotmc.org/nexus/content/repositories/snapshots/ codemc https://repo.codemc.org/repository/maven-public/ org.spigotmc spigot-api 1.20.1-R0.1-SNAPSHOT provided net.skinsrestorer skinsrestorer-api 15.12.6 provided org.apache.maven.plugins maven-compiler-plugin 3.14.1 ``` The Bukkit dependency supplies the compile-time API. Run the result on a compatible platform and Java runtime. Both dependencies use `provided`, so the server supplies them at runtime. ### Plugin metadata [#plugin-metadata] ```yaml title="src/main/resources/plugin.yml" name: ExampleSkin version: 1.0.0 main: example.ExampleSkinPlugin api-version: '1.20' depend: [SkinsRestorer] commands: exampleskin: description: Save and apply a Minecraft account skin usage: /exampleskin permission: exampleskin.use permissions: exampleskin.use: default: op ``` The hard dependency loads SkinsRestorer first. The example command is operator-only by default. ### Plugin implementation [#plugin-implementation] ```java title="src/main/java/example/ExampleSkinPlugin.java" package example; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.logging.Level; import net.skinsrestorer.api.SkinsRestorer; import net.skinsrestorer.api.SkinsRestorerProvider; import net.skinsrestorer.api.VersionProvider; import net.skinsrestorer.api.exception.DataRequestException; import net.skinsrestorer.api.exception.MineSkinException; import net.skinsrestorer.api.property.SkinProperty; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; public final class ExampleSkinPlugin extends JavaPlugin { private final Set pending = new HashSet<>(); private SkinsRestorer skinsRestorer; @Override public void onEnable() { try { skinsRestorer = SkinsRestorerProvider.get(); if (!VersionProvider.isCompatibleWith("15")) { throw new IllegalStateException("This example requires API major 15"); } } catch (IllegalStateException exception) { getLogger().log(Level.SEVERE, "SkinsRestorer API is unavailable", exception); getServer().getPluginManager().disablePlugin(this); } } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (!(sender instanceof Player player)) { sender.sendMessage("Run this command as a player."); return true; } if (args.length != 1 || !args[0].matches("[A-Za-z0-9_]{1,16}")) { return false; } UUID playerId = player.getUniqueId(); if (!pending.add(playerId)) { player.sendMessage("A skin request is already pending."); return true; } String accountName = args[0]; player.sendMessage("Fetching the skin..."); getServer().getScheduler().runTaskAsynchronously(this, () -> { try { var result = skinsRestorer.getSkinStorage() .findOrCreateSkinData(accountName); if (result.isEmpty()) { finish(player, playerId, null, "No skin found for that account."); return; } var skin = result.get(); skinsRestorer.getPlayerStorage() .setSkinIdOfPlayer(playerId, skin.getIdentifier()); finish(player, playerId, skin.getProperty(), null); } catch (DataRequestException | MineSkinException exception) { getLogger().log(Level.WARNING, "Skin lookup failed", exception); finish(player, playerId, null, "The skin service request failed."); } catch (RuntimeException exception) { getLogger().log(Level.SEVERE, "Skin storage operation failed", exception); finish(player, playerId, null, "The skin could not be saved."); } }); return true; } private void finish(Player originalPlayer, UUID playerId, SkinProperty property, String error) { if (!isEnabled()) { return; } getServer().getScheduler().runTask(this, () -> { pending.remove(playerId); Player currentPlayer = getServer().getPlayer(playerId); if (currentPlayer != originalPlayer || !currentPlayer.isOnline()) { return; } if (property == null) { currentPlayer.sendMessage(error); return; } skinsRestorer.getSkinApplier(Player.class) .applySkin(currentPlayer, property); currentPlayer.sendMessage("Skin saved. The server will refresh your appearance."); }); } } ``` The pending set stays on the server thread. The worker performs lookup and storage access. The callback avoids updating a disconnected or replaced player session. The saved selection remains if the player leaves during the request. The visual refresh only targets the original session. A saved selection and immediate appearance are separate results. SkinsRestorer's Bukkit applier schedules its own profile refresh. Other Bukkit operations, including messages and player access, still need the correct server thread. ## Build and check [#build-and-check] 1. Run `mvn package` in the project directory. 2. Stop the test server. 3. Copy `target/example-skin-1.0.0.jar` into `plugins`. 4. Start the server and read the startup log. 5. Join as an operator and run `/exampleskin xknat`. 6. Ask another player to check the skin. 7. Reconnect and check the saved selection. If startup says the API is unavailable on a backend, inspect [shared storage](/docs/development/proxy-api). If compilation fails, check the repository connection and both dependency versions. ## Extend the example [#extend-the-example] Add your own authorization, cooldown, and request policy before exposing this command broadly. API calls do not automatically enforce `/skin` command restrictions. For Folia, replace the Bukkit scheduling with an appropriate global or entity scheduler. Do not mark this example `folia-supported` without that work. Continue with [persistent and temporary changes](/docs/development/storage). # Develop with the Java API URL: /docs/development SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Build an integration that fetches, saves, and applies skin data. The public API gives Java plugins access to skin storage, player selections, generation services, and platform skin application. ## Start here [#start-here] 1. Build [your first plugin](/docs/development/first-plugin) with a complete Bukkit example. 2. Read [dependencies and lifecycle](/docs/development/api) for other build tools and platforms. 3. Choose [persistent or temporary application](/docs/development/storage). 4. Configure [backend API access](/docs/development/proxy-api) for a proxy network. The examples target **API 15.12.6**. Use the same API major as the installed plugin. Do not bundle the API or depend on internal implementation classes. ## API resources [#api-resources] * [Public Javadocs](https://jd.skinsrestorer.net). * [Release API source](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/api/src/main/java/net/skinsrestorer/api). * [Upstream example plugin](https://github.com/SkinsRestorer/SkinsRestorerAPIExample). The [skin lifecycle](/docs/development/inner-workings) explains identifiers, signed properties, and join resolution. Use [support diagnostics](/docs/troubleshooting/debugging) when an integration behaves differently from ordinary commands. # How a skin reaches a player URL: /docs/development/inner-workings SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Understand saved selections, cached properties, and profile application. A skin change has three separate pieces: an identifier, a signed texture property, and the profile that the client sees. ## From input to visible skin [#from-input-to-visible-skin] 1. A command or API consumer supplies a player name, URL, or custom name. 2. Skin storage resolves that input to an identifier and signed property. 3. Player storage saves the selected identifier if the operation is persistent. 4. The platform skin applier updates the player's profile. 5. Minecraft clients download and display the texture. A correct saved identifier does not prove that a client displays the property. A visible temporary change does not prove that the selection is saved. ## Skin sources [#skin-sources] * **Player skin:** Account data associated with a player UUID. * **URL skin:** A generated property associated with an image URL and model. * **Custom skin:** A named server entry containing a signed property. * **Recommended skin:** An entry supplied by the recommendations service. A custom entry can keep a snapshot of an account or URL texture under a stable server name. ## Resolution on join [#resolution-on-join] A saved player selection is separate from account skin lookup and server defaults. If no selection exists, account and default rules determine the resolved property. Online-mode join behavior also depends on `login.alwaysApplyPremium`. `advanced.disableOnJoinSkins` prevents automatic join application. The default list can choose one of several skins. With `storage.defaultSkins.applyForPremium: false`, account skins keep their normal priority over that fallback. ## Caching [#caching] Player skin and UUID caches reduce service requests. Their durations use minutes. A duration of zero requests fresh data on each lookup. Generated URL textures do not follow account skin changes. A changed PNG needs a new generation. A copied account skin can refresh with `/skin update`. ## Proxy networks [#proxy-networks] The proxy owns ordinary commands and selections. It forwards profile data to the backends. A backend API consumer needs access to the same SQL records. Read [proxy ownership](/docs/concepts/proxy) for that boundary, or [persistent and temporary API changes](/docs/development/storage) for implementation. # Use the API on a proxy network URL: /docs/development/proxy-api SkinsRestorer: 15.12.6 Applies to: Velocity / BungeeCord integrations and proxy backends Reviewed: 2026-10-01 Choose a proxy integration or give a backend access to shared skin storage. Choose where your integration runs before configuring storage. ## Integration on the proxy [#integration-on-the-proxy] Call the API from the proxy plugin and use that platform's player type. The proxy owns the ordinary saved selection and skin command behavior. A backend can communicate with your proxy plugin using an appropriate plugin-message protocol. Validate message sources and payloads in your integration. ## Integration on a backend [#integration-on-a-backend] You need all of these: * Correct player identity and profile forwarding. * SkinsRestorer on the proxy and backend. * `server.proxyMode.api: true` on the backend. * The same MySQL or PostgreSQL database and table prefix on both instances. * Working database access and successful API initialization on the backend. File storage does not support backend API initialization in proxy mode. ## Configure and check [#configure-and-check] 1. [Back up the current storage](/docs/configuration/backups). 2. Configure [shared SQL storage](/docs/configuration/database) on the proxy and API-enabled backends. 3. Restart the affected instances. 4. Inspect database and API initialization logs. 5. Change a skin through the proxy. 6. Resolve the same player's selected identifier through the backend plugin. 7. Switch backends and check the visible skin. Matching server names alone does not prove matching player UUIDs. Inspect forwarded identity if records disagree. ## If the provider is unavailable [#if-the-provider-is-unavailable] `SkinsRestorerProvider.get()` can throw when backend storage initialization fails. A plugin load-order dependency cannot fix missing shared storage. If no backend plugin needs the API, disable backend API access and keep ordinary proxy skin forwarding. Use [proxy troubleshooting](/docs/troubleshooting/proxy-mode). # Persistent and temporary skin changes URL: /docs/development/storage SkinsRestorer: 15.12.6 Applies to: Java plugins using API 15.12.6 Reviewed: 2026-10-01 Choose whether a change survives reconnects before calling the applier. Player storage saves an identifier. Skin storage resolves that identifier to a signed property. The skin applier changes a live profile. ## Persistent change [#persistent-change] The [complete plugin example](/docs/development/first-plugin) performs these operations: 1. Resolve input with `SkinStorage.findOrCreateSkinData(input)`. 2. Handle an empty result. 3. Save `result.getIdentifier()` with `PlayerStorage.setSkinIdOfPlayer(uuid, identifier)`. 4. Apply `result.getProperty()` to the live player with the platform's skin applier. The saved identifier controls future resolution. Applying the already-resolved property avoids another lookup during the immediate refresh. A storage write and a visual refresh are not one transaction. A player can disconnect after the selection saves. Keep that distinction in error messages. ## Temporary change [#temporary-change] `applySkin(player, property)` changes the live appearance without writing the selected identifier. The same is true of the identifier overload alone. Use this for previews or temporary effects. On reconnect, normal saved selection and default rules apply again. ## Apply the saved selection [#apply-the-saved-selection] `applySkin(player)` resolves the skin that would apply on join. It can throw `DataRequestException` because resolution can request account data. Do not assume that every overload performs the same storage work or throws the same checked exceptions. ## Generate a URL property [#generate-a-url-property] `MineSkinAPI.genSkin(url, SkinVariant.CLASSIC)` returns a generated property. It can throw `DataRequestException` and `MineSkinException`. Applying that property directly is temporary. For a persistent URL selection, use the skin storage resolution path and save its identifier, as the tutorial does. File and image generation overloads can also throw `IOException`. Inspect the [release API signatures](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/api/src/main/java/net/skinsrestorer/api) for the overload you use. ## Read or create data [#read-or-create-data] `PlayerStorage.getSkinForPlayer(uuid, name)` resolves a saved or fallback property and can throw `DataRequestException`. `SkinStorage.setCustomSkinData(name, property)` stores a named custom entry. Preserve the signed value and signature together. `PropertyUtils.getSkinTextureUrl(property)` extracts the skin URL. A texture URL alone is not a complete signed property. ## Failure policy [#failure-policy] Keep separate outcomes for missing input, service errors, storage errors, and disconnected players. Do not retry generation in a tight loop. The API does not automatically apply the command layer's cooldowns, per-skin permissions, or URL restrictions. Your integration must enforce its intended policy. For a proxy backend, configure [shared API storage](/docs/development/proxy-api) first. # Use skins with capes URL: /docs/features/capes SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Copy an equipped cape or select a supported cape during upload. A cape can be part of the same signed profile property as the skin. A client that receives this property can display both textures. ## Copy a player's equipped cape [#copy-a-players-equipped-cape] 1. Find a Minecraft account with the cape equipped. 2. Run `/skin set ` with that account name. 3. Ask another player to check the skin and cape. The copied property contains the skin and the equipped cape together. If the source account changes its cape, run `/skin update` to request fresh account data. ## Add a supported cape to an uploaded skin [#add-a-supported-cape-to-an-uploaded-skin] The website's [Upload](/upload) and [Generator](/generator) pages show cape choices supported by their generation route. 1. Upload your skin PNG. 2. Choose **Axolotl** for its supported capes, or **Official** with a key that grants cape access. 3. Choose a cape from the available list. 4. Generate the command. 5. Apply the command on the server. The list and service grants can change. If a cape is unavailable, inspect the available list and your API key grants. Do not assume every MineSkin key can generate every cape. ## Limits [#limits] * This changes the profile shown on a server. It does not grant a cape to your Microsoft account. * Arbitrary cape PNG uploads are not supported by these pages. * Editing signed texture data invalidates its signature. * Client cape mods can override the server-provided cape. A selected cape in **Axolotl** mode uses the website's cape-aware proxy route. **Official** mode uses MineSkin with your key. Read [skin properties and signatures](/docs/concepts/skin-properties) for the technical model, or [upload a PNG](/docs/features/skin-upload) to try it. # Change or reset your skin URL: /docs/features/change-skin SkinsRestorer: 15.12.6 Applies to: Players on a SkinsRestorer server Reviewed: 2026-10-01 Select a player skin, refresh it, or return to your account skin. These commands run in game chat. Replace `xknat` with the name of the Minecraft account whose skin you want. ## Change your skin [#change-your-skin] ```text /skin set xknat ``` Wait for the success message. Ask another player to check your appearance. The server saves your selection for future joins. `/skin xknat` is a shortcut. To apply your own PNG, use [the upload guide](/docs/features/skin-upload). ## Restore your account skin [#restore-your-account-skin] ```text /skin clear ``` This command removes your saved selection. The server then resolves your account skin or its configured default. It does not delete the source skin from storage. ## Refresh a copied account skin [#refresh-a-copied-account-skin] ```text /skin update ``` Use this after the source account changes its skin or cape. URL skins are cached generated textures. To change a URL skin, upload the revised image again. ## Undo a change [#undo-a-change] ```text /skin undo ``` Undo uses the server's saved skin history. If history is disabled or empty, there is no previous selection to restore. ## If the command fails [#if-the-command-fails] * **Permission denied:** Ask the administrator to check [player access](/docs/configuration/player-access). * **Cooldown:** Wait for the displayed time. Repeated attempts do not speed up a request. * **Skin cannot load:** Check the account name, then ask the administrator to inspect [service connections](/docs/troubleshooting/firewall). * **Success without a visible change:** Use [profile troubleshooting](/docs/troubleshooting/no-skin). Continue with [the skin menu and favorites](/docs/features/skin-menu). # Create a named custom skin URL: /docs/features/custom-skins SkinsRestorer: 15.12.6 Applies to: Server and proxy administrators Reviewed: 2026-10-01 Save a reusable server skin for commands, defaults, and the menu. A custom skin gives a signed texture a server-owned name, such as `lobby`. Players can then use `/skin set lobby`. ## Before you start [#before-you-start] You need console access or `skinsrestorer.admincommand.createcustom`. On a network, create the skin through the proxy that owns skin storage. ## Create from a PNG [#create-from-a-png] 1. Open [Generator](/generator). 2. Choose your skin PNG. 3. Enter a short skin name, such as `lobby`. 4. Choose **Classic** or **Slim**. 5. Choose the generation method and select a supported cape if you need one. 6. Select **Generate /sr createcustom command**. 7. Run the generated command in the server or proxy console. The generator returns a command. It does not download a storage file or install the skin on your server. ## Create from a player name or URL [#create-from-a-player-name-or-url] ```text /sr createcustom lobby xknat ``` For an image URL, keep the URL quoted and specify the model: ```text title="Replace the example URL with a real skin PNG" /sr createcustom lobby "https://example.com/lobby.png" classic ``` Creating an existing name updates that custom skin. Back up valuable custom skins before replacement. ## Check and reuse [#check-and-reuse] 1. Run `/skin set lobby` in game. 2. Check the appearance from another player. 3. Run `/sr info skin lobby` to inspect the stored texture. Use `lobby` in a [default skin list](/docs/configuration/default-skins) or the [custom menu list](/docs/configuration/skin-menu). To change the menu label, run `/sr setcustomname lobby Lobby skin`. The command uses the same permission as `createcustom`. ## Existing skin files [#existing-skin-files] The generator's reverse conversion can read supported existing skin storage files. Use it to recover the texture for editing. Do not hand-edit a texture value or signature. Read [storage and backups](/docs/configuration/backups) before you remove stored data. # Use skins URL: /docs/features SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Change a skin, upload a PNG, or browse saved skins. Your server must have SkinsRestorer installed. A server administrator controls command access and cooldowns. ## Choose a task [#choose-a-task] * [Change or reset your skin](/docs/features/change-skin): Use a player name and restore your account skin. * [Upload a PNG](/docs/features/skin-upload): Generate a command from your own skin image. * [Browse skins and save favorites](/docs/features/skin-menu): Open the menu, undo a change, and reuse a skin. * [Edit your current skin](/docs/features/skin-edit): Open an editor and apply the exported PNG. * [Choose classic or slim](/docs/features/skin-design): Fix arm artifacts and understand the image format. * [Use a cape](/docs/features/capes): Understand copied capes and supported upload options. Server owners can also [create named custom skins](/docs/features/custom-skins) for a menu or default skin list. ## Before you ask for support [#before-you-ask-for-support] If a command is denied, use [permission troubleshooting](/docs/troubleshooting/permissions). If it succeeds but nothing changes, use [no visible skin](/docs/troubleshooting/no-skin). # Classic, slim, and skin images URL: /docs/features/skin-design SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Choose the model that matches your skin and avoid image-format problems. A skin PNG is a texture template. Each part of the image maps to the head, body, arms, or legs. ## Classic or slim [#classic-or-slim] | Model | Arm width | Command value | | --------------- | ------------ | ------------- | | Classic / Steve | Four pixels | `classic` | | Slim / Alex | Three pixels | `slim` | The model must match the template. The wrong model can produce black lines, gaps, or misplaced arm pixels. The upload preview helps you check the result before generation. ## Image format [#image-format] Use a standard **64 × 64 PNG** for a new skin. Legacy **64 × 32** skins exist, but support can depend on the upload service and conversion path. The base body layer needs opaque pixels. The outer layer can contain transparent pixels for hats, sleeves, and other details. A standard Java client does not display arbitrary HD skin sizes. Minecraft's Skin Customization controls can hide outer-layer parts. A hidden hat layer does not mean the server failed to apply a skin. For format details, use [Minecraft's skin help](https://help.minecraft.net/hc/en-us/articles/4408894664461-Minecraft-Skins-for-Java-Edition). ## Prepare an image [#prepare-an-image] 1. Open a template in a skin editor or image editor. 2. Keep the original canvas dimensions. 3. Export a PNG without image scaling. 4. Choose the matching model on [Upload](/upload). 5. Inspect the preview before generation. An image viewer can blur pixels during zoom. Use a pixel view to inspect the original file. ## Next [#next] [Upload the PNG](/docs/features/skin-upload), or [edit your current skin](/docs/features/skin-edit). # Edit your current skin URL: /docs/features/skin-edit SkinsRestorer: 15.12.6 Applies to: Players on a SkinsRestorer server Reviewed: 2026-10-01 Open the editor, export a PNG, and apply the revised skin. `/skin edit` gives you a browser link for your current skin. The editor does not save changes directly to the server. ## Before you start [#before-you-start] You need `skinsrestorer.command.edit` for the editor link and `skinsrestorer.command.set.url` for the upload command. ## Edit and apply [#edit-and-apply] 1. Run `/skin edit` in game chat. 2. Open the editor link from the message. 3. Change the skin in the editor. 4. Export or save the two-dimensional PNG template. 5. Open [Upload](/upload). 6. Upload the PNG and choose its model. 7. Generate and run the `/skin url` command. Editor controls can change. Save the skin template, rather than a screenshot of the three-dimensional preview. The new selection must remain after a reconnect. If the arms show gaps, choose the other [model](/docs/features/skin-design) and generate again. ## If the link is unavailable [#if-the-link-is-unavailable] Use your original PNG in a skin editor, then follow [the upload guide](/docs/features/skin-upload). If the command itself is denied, ask the administrator to check the edit permission. # Browse skins and save favorites URL: /docs/features/skin-menu SkinsRestorer: 15.12.6 Applies to: Players on platforms with inventory GUI support Reviewed: 2026-10-01 Use the menu, skin history, search links, and favorites. The skin menu is available on platforms that support its inventory UI. Your administrator controls which categories appear. ## Open the menu [#open-the-menu] Run `/skins` or `/skin menu`. Choose a skin from the available entries. If the menu is empty, the administrator can [configure its categories](/docs/configuration/skin-menu). Recommended skins depend on `api.fetchRecommendedSkins`. Named custom skins come from server storage. These are different sources. ## Save a favorite [#save-a-favorite] 1. Select a skin with `/skin set ` or `/skin url ""`. 2. Run `/skin favourite`. 3. Run `/skin favourites` to view saved choices. `/skin favourite` toggles the current selection. Run it again on the same selection to remove that favorite. The command uses the British spelling `favourite`. History and favorites have separate server limits. ## Reuse a previous skin [#reuse-a-previous-skin] Run `/skin history` to view previous selections. Run `/skin undo` to restore the previous selection. The history permission is `skinsrestorer.command.undo`. ## Search for a skin [#search-for-a-skin] Run `/skin search ` to receive a search link. This command does not automatically choose a result. Download the chosen PNG and [upload it](/docs/features/skin-upload). ## If access is denied [#if-access-is-denied] Menu access needs `skinsrestorer.command.gui`. Favorites need `skinsrestorer.command.favourite`. Ask the administrator to inspect [the command reference](/docs/configuration/commands-permissions). # Upload a PNG skin URL: /docs/features/skin-upload SkinsRestorer: 15.12.6 Applies to: Website users and Java server players Reviewed: 2026-10-01 Turn a PNG into a /skin url command and apply it in game. Use the [skin upload page](/upload) to generate a command from a skin PNG. The page does not connect to your Minecraft server. You apply the result yourself. ## Before you start [#before-you-start] You need a Minecraft skin PNG and permission for `skinsrestorer.command.set.url`. The website accepts PNG files up to 5 MB. Use a standard skin template, rather than a screenshot or an HD texture. Read [classic and slim models](/docs/features/skin-design) if you are unsure which model matches your image. ## Generate and apply [#generate-and-apply] 1. Open [Upload](/upload). 2. Select **Browse files** and choose your PNG. 3. Check the preview and choose **Classic** or **Slim**. 4. Choose **Axolotl** or **Official** under **Upload method**. 5. If you want a cape, select one from the available cape list. 6. Select **Generate /skin url**. 7. Copy the generated command. 8. Paste the command into your Minecraft chat. Keep the generated URL inside quotation marks. The command includes the model selected on the page. A result can use a MineSkin URL or an opaque `skinsrestorer-axolotl://` value. Copy that value exactly. An Axolotl value is for the command, rather than a browser link. ```text title="Command shape, not a ready-to-use texture URL" /skin url "https://textures.minecraft.net/texture/TEXTURE_HASH" slim ``` Wait for a success message. Ask another player to check your skin, then reconnect to check persistence. ## API key and capes [#api-key-and-capes] The **Axolotl** method offers supported capes without your own key. The **Official** method accepts a MineSkin key and checks its cape grants. A selected cape with **Axolotl** uses the proxy route. **Official** uploads and uploads without a selected cape use MineSkin directly. The key field on the website and `api.mineskinAPIKey` on your server are separate. Read [MineSkin integration](/docs/integrations/mineskin) for queues, limits, and privacy. The available list contains supported existing capes. It does not accept arbitrary cape images or transfer cape ownership to your account. ## If generation fails [#if-generation-fails] * **Invalid image:** Export a standard PNG skin template again. * **Queue or rate limit:** Wait for the queue to finish before you retry. * **Unauthorized key:** Check the key and its current account grants. * **Arm artifacts:** Generate again with the [correct model](/docs/features/skin-design). * **Command denied:** Check [URL permissions and restrictions](/docs/configuration/restrict-skins). To give the result a reusable server name, [create a custom skin](/docs/features/custom-skins). # Install on Paper or Spigot URL: /docs/installation/bukkit SkinsRestorer: 15.12.6 Applies to: Paper, Spigot, Bukkit Reviewed: 2026-10-01 Install the plugin on a standalone Bukkit-compatible server. By the end of this guide, your server will load SkinsRestorer and accept a skin change. ## Before you start [#before-you-start] You need file access, console access, and a supported [Java runtime](/docs/installation/requirements). If players connect through a proxy, use the [Velocity](/docs/installation/velocity) or [BungeeCord](/docs/installation/bungeecord) guide instead. ## Install [#install] 1. Stop the server. 2. Download the server/proxy JAR from the [15.12.6 release](https://github.com/SkinsRestorer/SkinsRestorer/releases/tag/15.12.6). 3. Remove older SkinsRestorer JARs from `plugins`. Keep the existing data folder. 4. Put the new JAR in `plugins`. 5. Start the server. 6. Read the console for SkinsRestorer startup errors. The plugin creates `plugins/SkinsRestorer/config.yml`. Keep the defaults for this first check. Do not use the server-wide `/reload` command to install or update plugins. ## Check the installation [#check-the-installation] 1. Join the server with a Java client. 2. Run `/skin set xknat`. 3. Ask another player to check your skin. 4. Reconnect and check that the selection remains. If the command is unavailable, check the startup log and `commands.disableSkinCommand`. If access is denied, read [player access](/docs/configuration/player-access). If the command succeeds but the skin stays unchanged, use [no visible skin](/docs/troubleshooting/no-skin). ## Next [#next] [Upload your own PNG](/docs/features/skin-upload), or configure [default skins](/docs/configuration/default-skins). # Install on a BungeeCord network URL: /docs/installation/bungeecord SkinsRestorer: 15.12.6 Applies to: BungeeCord networks Reviewed: 2026-10-01 Forward player profiles and install SkinsRestorer on the proxy and backends. SkinsRestorer runs on BungeeCord and each backend. The proxy manages skin commands and sends the selected profile to backends. ## Before you start [#before-you-start] You need access to the proxy and every backend. Legacy forwarding requires backend protection. Read [backend security](/docs/troubleshooting/firewall#protect-proxy-backends) before you expose the network. ## Configure forwarding [#configure-forwarding] 1. Stop the proxy and backends. 2. Enable IP forwarding in the proxy configuration. 3. Enable BungeeCord forwarding on each Bukkit backend. 4. Disable account authentication on the backends. ```yaml title="BungeeCord config.yml (excerpt)" ip_forward: true ``` ```yaml title="Backend spigot.yml (excerpt)" settings: bungeecord: true ``` ```properties title="Backend server.properties (excerpt)" online-mode=false ``` Keep the proxy's authentication policy separate from backend configuration. Do not disable proxy authentication just to use skins. ## Install [#install] 1. Put the server/proxy SkinsRestorer JAR in the proxy's `plugins` folder. 2. Install the same release on every backend. 3. Start the backends and proxy. 4. Read all startup logs. A modded backend needs the matching mod artifact and compatible forwarding support. Leave backend `server.proxyMode.detection` at `AUTO` unless detection fails. ## Check [#check] Complete the [first skin check](/docs/installation/quick-start), including a switch between backends. Grant command permissions on BungeeCord or its proxy permission plugin. Ordinary proxy-managed skins do not require SQL storage. Backend API integrations need [shared storage](/docs/development/proxy-api). ## If it fails [#if-it-fails] If only one backend shows the skin, compare its forwarding configuration and installed release with a working backend. Use [proxy troubleshooting](/docs/troubleshooting/proxy-mode) for mode warnings and duplicate commands. # Install on Fabric URL: /docs/installation/fabric SkinsRestorer: 15.12.6 Applies to: Fabric servers Reviewed: 2026-10-01 Install the Fabric mod and check a server skin change. This guide covers a standalone Fabric server. A proxy backend also needs compatible profile forwarding and proxy mode. ## Before you start [#before-you-start] Match the mod download to your Minecraft version. SkinsRestorer 15.12.6 targets Minecraft 26.3. Read the [requirements](/docs/installation/requirements) before you update an existing modpack. The packaged Fabric release includes Fabric API, Cloud, and the permissions API. Do not use the raw development JAR. ## Install [#install] 1. Stop the server. 2. Download the Fabric artifact from the [official release](https://github.com/SkinsRestorer/SkinsRestorer/releases/tag/15.12.6). 3. Remove older SkinsRestorer mod JARs from `mods`. Keep the configuration and data. 4. Put the new mod JAR in `mods`. 5. Start the server. 6. Read the log for loader dependency errors and SkinsRestorer startup errors. Use the configuration location reported by the mod. Do not copy a Bukkit plugin JAR into `mods`. ## Check [#check] 1. Join the server. 2. Run `/skin set xknat`. 3. Ask another player to check your skin. 4. Reconnect and check that the selection remains. If access is denied, configure the platform's permissions or read [player access](/docs/configuration/player-access). If the loader rejects the mod, compare Minecraft, Java, and loader versions with the artifact requirements. ## Next [#next] Complete the [first skin check](/docs/installation/quick-start), then [upload a PNG](/docs/features/skin-upload). # Install SkinsRestorer URL: /docs/installation SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Choose the installation guide for your server or proxy. Choose the software that accepts your players' connections. Do not choose an artifact by its filename alone. ## Choose your setup [#choose-your-setup] | Setup | Installation guide | Where SkinsRestorer runs | | ----------------------------------- | ------------------------------------------- | ----------------------------- | | One Paper, Spigot, or Bukkit server | [Paper / Spigot](/docs/installation/bukkit) | The server's `plugins` folder | | Velocity network | [Velocity](/docs/installation/velocity) | The proxy and every backend | | BungeeCord network | [BungeeCord](/docs/installation/bungeecord) | The proxy and every backend | | Standalone Fabric server | [Fabric](/docs/installation/fabric) | The server's `mods` folder | | Standalone NeoForge server | [NeoForge](/docs/installation/neoforge) | The server's `mods` folder | The server/proxy plugin and the Fabric/NeoForge mods are separate downloads. A Bukkit plugin does not run as a Fabric mod. ## Before you start [#before-you-start] 1. Read the [requirements](/docs/installation/requirements) for your platform. 2. Download an artifact from the [official releases](https://github.com/SkinsRestorer/SkinsRestorer/releases/tag/15.12.6). 3. Back up the server configuration and existing SkinsRestorer data. 4. Follow one installation guide. 5. Complete the [first skin check](/docs/installation/quick-start). SkinsRestorer works with online and offline server authentication. Do not disable authentication just to install it. Proxy backends require their own forwarding configuration. # Install on NeoForge URL: /docs/installation/neoforge SkinsRestorer: 15.12.6 Applies to: NeoForge servers Reviewed: 2026-10-01 Install the NeoForge mod and check a server skin change. This guide covers a standalone NeoForge server. A proxy backend also needs compatible profile forwarding and proxy mode. ## Before you start [#before-you-start] Match the mod download to your Minecraft version. SkinsRestorer 15.12.6 targets Minecraft 26.3. Read the [requirements](/docs/installation/requirements) before you update an existing modpack. Use a matching NeoForge loader. The 15.12.6 build targets NeoForge 26.3.0.7-beta. ## Install [#install] 1. Stop the server. 2. Download the NeoForge artifact from the [official release](https://github.com/SkinsRestorer/SkinsRestorer/releases/tag/15.12.6). 3. Remove older SkinsRestorer mod JARs from `mods`. Keep the configuration and data. 4. Put the new mod JAR in `mods`. 5. Start the server. 6. Read the log for loader dependency errors and SkinsRestorer startup errors. Use the configuration location reported by the mod. Do not copy a Bukkit plugin JAR into `mods`. ## Check [#check] 1. Join the server. 2. Run `/skin set xknat`. 3. Ask another player to check your skin. 4. Reconnect and check that the selection remains. If access is denied, configure the platform's permissions or read [player access](/docs/configuration/player-access). If the loader rejects the mod, compare Minecraft, Java, and loader versions with the artifact requirements. ## Next [#next] Complete the [first skin check](/docs/installation/quick-start), then [upload a PNG](/docs/features/skin-upload). # Check your first skin URL: /docs/installation/quick-start SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Check commands, persistence, and network switching after installation. Run this check after your [platform installation](/docs/installation). It separates command access, skin fetching, and profile application. ## First change [#first-change] 1. Join the server with a Java client. 2. Run `/skin set xknat`. 3. Wait for the success message. 4. Ask another player to check your appearance. 5. Disconnect and join again. Your selected skin must remain after you reconnect. Your own client can briefly show an older skin, so use another player's view too. ## Proxy network check [#proxy-network-check] 1. Connect through the proxy address. 2. Change your skin on the first backend. 3. Switch to a second backend. 4. Check your skin again. If it changes on one backend only, use [proxy troubleshooting](/docs/troubleshooting/proxy-mode). Do not add a database just because the network has several servers. ## Return to your account skin [#return-to-your-account-skin] Run `/skin clear`. This removes your saved selection. Account lookup and server default rules then determine your skin. ## If a check fails [#if-a-check-fails] | Result | Next step | | ------------------------------------ | ------------------------------------------------------------------ | | Unknown command | Read the startup log and check the installed artifact | | Permission denied | [Check permissions](/docs/troubleshooting/permissions) | | Name or URL cannot load | [Check service connections](/docs/troubleshooting/firewall) | | Success message, unchanged skin | [Check profile application](/docs/troubleshooting/no-skin) | | Selection disappears after reconnect | [Check join and proxy behavior](/docs/troubleshooting/skin-resets) | After these checks pass, read [change or reset a skin](/docs/features/change-skin). # Requirements and compatibility URL: /docs/installation/requirements SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Match the SkinsRestorer artifact, Minecraft version, and Java runtime. There are three release artifacts: a server/proxy plugin, a Fabric mod, and a NeoForge mod. Mod builds target specific Minecraft versions. ## Server and proxy plugins [#server-and-proxy-plugins] Use the server/proxy artifact on Bukkit-compatible servers, BungeeCord, and Velocity. Choose a Java runtime that satisfies both your platform and the plugin release. The platform can require a newer Java version than SkinsRestorer. Read [Paper's requirements](https://docs.papermc.io/paper/getting-started/) or [Velocity's requirements](https://docs.papermc.io/velocity/getting-started/) for your exact release. Forks and hybrid mod/plugin servers can change profile behavior. A successful startup alone does not prove compatibility. Reproduce problems on an upstream platform before you report a [platform conflict](/docs/troubleshooting/incompatibility-list). ## Fabric and NeoForge 15.12.6 [#fabric-and-neoforge-15126] The source for this release targets **Minecraft 26.3**. The Fabric metadata requires Java 25 or newer and Fabric Loader 0.16.0 or newer. The build uses Fabric Loader 0.19.5. The NeoForge build targets NeoForge 26.3.0.7-beta. Use the loader and Java runtime required by that Minecraft release. An older Minecraft server needs a matching older SkinsRestorer mod artifact. These values come from the [release build configuration](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/gradle.properties) and [Fabric metadata](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/mod/fabric/src/main/resources/fabric.mod.json). ## Clients and networks [#clients-and-networks] Players do not need the Bukkit plugin on their client. The server sends skin properties to Java clients. Client skin mods can override those properties. A proxy network needs correct UUID and profile forwarding before skin troubleshooting. For Velocity, use the [official forwarding guide](https://docs.papermc.io/velocity/player-information-forwarding/). Bedrock clients and custom client renderers can handle skins differently. Do not use their appearance as the only check of a Java server skin change. ## Downloads and dependencies [#downloads-and-dependencies] Use the packaged release artifact, rather than a `raw` development JAR. The Fabric release bundles Fabric API, Cloud, and the Fabric permissions API. If the loader reports a missing dependency, inspect the artifact and loader versions first. Continue with [your installation guide](/docs/installation). # Install on a Velocity network URL: /docs/installation/velocity SkinsRestorer: 15.12.6 Applies to: Velocity with Paper backends Reviewed: 2026-10-01 Configure forwarding and install SkinsRestorer on the proxy and backends. This guide covers Velocity with Paper backends. For a modded backend, configure its forwarding support using the [Velocity compatibility guide](https://docs.papermc.io/velocity/server-compatibility/). ## Before you start [#before-you-start] You need access to the proxy and every backend. Players must connect through the proxy. Backend ports must accept connections only from trusted sources. Modern forwarding requires compatible Minecraft versions and backends. Read the [official forwarding instructions](https://docs.papermc.io/velocity/player-information-forwarding/) before you choose a different mode. ## Configure modern forwarding [#configure-modern-forwarding] 1. Stop the proxy and backends. 2. Set `player-info-forwarding-mode` to `modern` in `velocity.toml`. 3. Read the proxy's `forwarding.secret` file. 4. Configure each Paper backend with that same secret. ```toml title="velocity.toml (excerpt)" player-info-forwarding-mode = "modern" ``` ```properties title="Backend server.properties (excerpt)" online-mode=false ``` ```yaml title="Backend config/paper-global.yml (Paper 1.19+ excerpt)" proxies: velocity: enabled: true online-mode: true secret: "YOUR_FORWARDING_SECRET" ``` Set `proxies.velocity.online-mode` to the proxy's `online-mode` value. The `true` value above assumes an authenticated proxy. Keep `settings.bungeecord` disabled in `spigot.yml` for modern forwarding. Paper 1.18.2 and older use `settings.velocity-support` in `paper.yml`. Use the platform guide for those releases. ## Install SkinsRestorer [#install-skinsrestorer] 1. Put the server/proxy SkinsRestorer JAR in the proxy's `plugins` folder. 2. Put the same release in every Bukkit backend's `plugins` folder. 3. Start the backends and proxy. 4. Read all startup logs for forwarding or SkinsRestorer errors. For Fabric or NeoForge backends, install the matching mod artifact instead of a Bukkit JAR. Leave `server.proxyMode.detection: AUTO` on the backends unless detection fails. Correct forwarding normally lets SkinsRestorer detect the proxy. ## Check [#check] Complete the [first skin and server-switch check](/docs/installation/quick-start). Skin commands use proxy permissions, so grant access on the proxy. The default file storage is enough for ordinary proxy-managed skins. A backend plugin that calls the API needs [shared MySQL or PostgreSQL storage](/docs/development/proxy-api). ## If it fails [#if-it-fails] An invalid forwarding secret is a connection problem. Fix it before you change skin configuration. For backend mode warnings or commands that work on one server only, use [proxy troubleshooting](/docs/troubleshooting/proxy-mode). # Build an avatar URL URL: /docs/integrations/avatar-url SkinsRestorer: 15.12.6 Applies to: Bukkit plugins that expand PlaceholderAPI avatar fields Reviewed: 2026-10-01 Use a texture hash to show the selected skin in another plugin. An account UUID avatar can show the account's original skin. A texture-hash avatar can show the texture currently applied by SkinsRestorer. ## Before you start [#before-you-start] The consuming plugin must support PlaceholderAPI in its avatar URL field. Install [PlaceholderAPI and check the texture placeholder](/docs/integrations/placeholderapi). ## Configure an avatar [#configure-an-avatar] Use this URL in the consuming plugin's avatar field: ```text https://mc-heads.net/avatar/%skinsrestorer_texture_id_or_steve%.png ``` Reload that plugin using its supported procedure. Change the player's skin, then trigger a new avatar or message. ## Diagnose the result [#diagnose-the-result] * **Literal placeholder:** The field does not expand PlaceholderAPI, or the expansion did not load. * **`Error`:** Inspect the SkinsRestorer log and data resolution. * **Correct hash, old avatar:** Inspect the image service or consuming application's cache. * **Steve fallback:** The placeholder has no resolved skin property. MC-Heads is an external renderer. Its availability is separate from server skin application. Use the focused guides for [DiscordSRV](/docs/integrations/discordsrv) and [Discord-MC-Chat](/docs/integrations/discord-mc-chat). # Show skins in Discord-MC-Chat URL: /docs/integrations/discord-mc-chat SkinsRestorer: 15.12.6 Applies to: Discord-MC-Chat 2.7.0; version-specific configuration Reviewed: 2026-10-01 Use the applied profile texture in DMCC 2.7 avatar URLs. This example applies to **Discord-MC-Chat 2.7.0's JSON configuration**. DMCC 3 uses a different configuration structure. Do not copy the JSON into a DMCC 3 YAML file. ## Before you start [#before-you-start] Complete DMCC's bot and channel setup. Install compatible mod releases for your Minecraft version. The example uses the profile texture that the game server applies. ## Configure DMCC 2.7 [#configure-dmcc-27] 1. Back up `config/discord-mc-chat.json`. 2. Find `avatarApi` inside the existing `generic` object. 3. Replace that value: ```json title="config/discord-mc-chat.json (partial object)" { "generic": { "avatarApi": "https://mc-heads.net/avatar/{player_textures}.png" } } ``` This is an excerpt. Keep the other fields in the file. The `generic.avatarApi` key and `{player_textures}` token come from the [DMCC 2.7 source](https://github.com/Xujiayao/Discord-MC-Chat/tree/2.7.0/src/main/java/com/xujiayao/discord_mc_chat). 4. Restart or use the reload command supported by your DMCC version. 5. Change a skin, then send a new chat message. 6. Check the avatar on the new message. ## DMCC 3 and other releases [#dmcc-3-and-other-releases] Use [DMCC's documentation](https://dmcc.xujiayao.com/) for your installed version's avatar configuration and available profile placeholders. Do not assume the 2.7 token or reload syntax remains unchanged. ## If it fails [#if-it-fails] First check that another Java client sees the server-selected skin. Then check DMCC's resolved avatar URL and logs. If the game profile itself is wrong, use [skin troubleshooting](/docs/troubleshooting/no-skin). # Show skins in DiscordSRV URL: /docs/integrations/discordsrv SkinsRestorer: 15.12.6 Applies to: Bukkit-compatible servers with DiscordSRV and PlaceholderAPI Reviewed: 2026-10-01 Use the current profile texture for player message avatars. This guide changes DiscordSRV's player avatar source. Complete DiscordSRV's bot and channel setup first. ## Before you start [#before-you-start] Install SkinsRestorer, DiscordSRV, and PlaceholderAPI on the same Bukkit-compatible server. Restart the server, then [check the texture placeholder](/docs/integrations/placeholderapi). ## Configure the avatar [#configure-the-avatar] 1. Back up `plugins/DiscordSRV/config.yml`. 2. Replace its existing `AvatarUrl` value: ```yaml title="plugins/DiscordSRV/config.yml (excerpt)" AvatarUrl: "https://mc-heads.net/avatar/%skinsrestorer_texture_id_or_steve%.png#{texture}" ``` 3. Run `/discord reload`. 4. Change your skin and send a new chat message. 5. Check the new message's avatar in Discord. The URL uses a skin texture hash instead of an account UUID. The `{texture}` fragment follows DiscordSRV's cache workaround. DiscordSRV documents both this fragment and PlaceholderAPI support in [its AvatarUrl reference](https://docs.discordsrv.com/config/#avatarurl). ## If the avatar is unchanged [#if-the-avatar-is-unchanged] Parse the PlaceholderAPI value first. If it is literal or `Error`, fix that before changing DiscordSRV. If the hash is correct, open the resulting avatar URL and compare a newly sent message. Discord can cache older avatars. Also inspect DiscordSRV's linked-account avatar configuration if it uses Discord avatars. For backend storage requirements, read [proxy API setup](/docs/development/proxy-api). # Integrations URL: /docs/integrations SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Show selected skins in placeholders, avatars, and chat bridges. Choose the integration for your platform. A Bukkit PlaceholderAPI expansion is not a Fabric placeholder system. | Integration | Platform | Purpose | | ----------------------------------------------------- | ----------------------------------------- | ---------------------------------------------- | | [PlaceholderAPI](/docs/integrations/placeholderapi) | Bukkit-compatible servers | Selected skin identifiers and current textures | | [DiscordSRV](/docs/integrations/discordsrv) | Bukkit-compatible servers | Player avatars in Discord | | [Discord-MC-Chat](/docs/integrations/discord-mc-chat) | Supported DMCC mod versions | Profile texture avatars | | [Avatar URLs](/docs/integrations/avatar-url) | Plugins with placeholder support | Render a texture as a player head | | [MineSkin](/docs/integrations/mineskin) | Server URL generation and website uploads | Generate signed skin properties | A proxy backend that resolves stored skin data through the API needs [shared storage](/docs/development/proxy-api). A placeholder that reads an online profile and one that reads a saved selection can return different information. For your own Java integration, start with [the developer tutorial](/docs/development/first-plugin). # MineSkin keys and generation URL: /docs/integrations/mineskin SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Understand signed skin generation, service limits, and optional API keys. MineSkin turns a skin image into a signed property that Minecraft clients can use. It is an external service with its own queues and limits. ## Server URL generation [#server-url-generation] `/skin url` and URL-based custom skins use skin generation when needed. You can configure an optional server key: ```yaml title="config.yml (SkinsRestorer excerpt)" api: mineskinAPIKey: "REPLACE_WITH_YOUR_API_KEY" mineskinSecretSkins: true ``` Run `/sr reload`. Try one valid URL and inspect the result. Keep the key private. The spelling and capitalization of `mineskinAPIKey` are significant. `mineskinSecretSkins: true` requests an unlisted generated skin. It does not make a Minecraft texture URL private or prevent others from copying it. ## Website generation [#website-generation] The [Upload](/upload) and [Generator](/generator) pages accept their own optional key. They do not read your server configuration. Choose **Axolotl** for the free supported-cape route. Choose **Official** to supply your MineSkin key and check its cape grants. The Axolotl route handles uploads with a selected cape in Axolotl mode. Plain uploads and Official-mode uploads use MineSkin's queue directly. Generated commands can contain a MineSkin URL or an opaque `skinsrestorer-axolotl://` value. SkinsRestorer resolves that opaque value through Axolotl when the command runs. The server's generation API and the website's queue are separate request paths. Success on one does not prove the other works. ## Limits and keys [#limits-and-keys] Use [MineSkin's API key page](https://mineskin.org/apikey) for current access and plan limits. Use [MineSkin's documentation](https://docs.mineskin.org/) for current generation behavior. Do not assume a paid key permits every cape. The website checks available cape grants and supported cape choices. ## Failures [#failures] * **Rate limit or queue delay:** Wait before another request. * **Invalid image or URL:** Use a reachable standard PNG skin template. * **Authorization error:** Check the key and its grants. * **Transport error:** Inspect [outbound connections](/docs/troubleshooting/firewall). For account-name lookups, SkinsRestorer uses account services instead of image generation. Mojang batching configuration does not change MineSkin limits. # PlaceholderAPI URL: /docs/integrations/placeholderapi SkinsRestorer: 15.12.6 Applies to: Bukkit-compatible servers with PlaceholderAPI Reviewed: 2026-10-01 Read selected skin identifiers and current textures on Bukkit servers. SkinsRestorer registers its expansion when PlaceholderAPI is available. You do not need to download a separate SkinsRestorer expansion from eCloud. ## Before you start [#before-you-start] Install SkinsRestorer and [PlaceholderAPI](https://github.com/PlaceholderAPI/PlaceholderAPI) on the same Bukkit-compatible server. Restart after installation. On a proxy backend, configure [backend API storage](/docs/development/proxy-api) if the integration needs saved selections or offline skin resolution. ## Check one placeholder [#check-one-placeholder] 1. Select a skin with `/skin set xknat`. 2. Run `/papi parse me %skinsrestorer_texture_id_or_steve%`. 3. Check that the result is a texture hash, rather than the original placeholder text. If the placeholder stays literal, inspect plugin loading and the consuming plugin's PlaceholderAPI support. `Error` means the expansion ran but could not provide the requested value. ## Selected skin identifier [#selected-skin-identifier] | Placeholder | No saved selection | | ------------------------------------------ | ------------------ | | `%skinsrestorer_skin_name%` | `Error` | | `%skinsrestorer_skin_name_or_empty%` | Empty string | | `%skinsrestorer_skin_name_or_player_name%` | Player name | These values describe the saved identifier. They do not guarantee that a skin is currently visible on the client. ## Texture URL [#texture-url] | Placeholder | No resolved skin | | -------------------------------------- | ----------------- | | `%skinsrestorer_texture_url%` | `Error` | | `%skinsrestorer_texture_url_or_empty%` | Empty string | | `%skinsrestorer_texture_url_or_steve%` | Steve texture URL | | `%skinsrestorer_texture_url_or_alex%` | Alex texture URL | ## Texture hash [#texture-hash] | Placeholder | No resolved skin | | ------------------------------------- | ------------------ | | `%skinsrestorer_texture_id%` | `Error` | | `%skinsrestorer_texture_id_or_empty%` | Empty string | | `%skinsrestorer_texture_id_or_steve%` | Steve texture hash | | `%skinsrestorer_texture_id_or_alex%` | Alex texture hash | Online texture placeholders read the current profile. Offline resolution uses storage and can require a service request. A request error returns `Error` and records a log entry, even for a fallback placeholder. A texture hash is the final identifier in a Minecraft texture URL. It is different from a player UUID. Continue with [DiscordSRV](/docs/integrations/discordsrv) or [avatar URLs](/docs/integrations/avatar-url). # Common questions URL: /docs/troubleshooting/common-issues SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Answers to common setup, skin, and storage questions. ## Do I need offline mode? [#do-i-need-offline-mode] No. SkinsRestorer supports online and offline authentication. Keep your authentication policy. A proxy backend has separate forwarding requirements. ## Do I need a database for a network? [#do-i-need-a-database-for-a-network] Ordinary proxy-managed skins do not require SQL. A backend API consumer in proxy mode needs shared MySQL or PostgreSQL storage. Read [proxy mode](/docs/troubleshooting/proxy-mode) before you change storage. ## Why does clear not always show Steve? [#why-does-clear-not-always-show-steve] `/skin clear` removes the saved selection. Account skin lookup and default skin rules determine the result afterward. ## Why does the URL image not change after I edit it? [#why-does-the-url-image-not-change-after-i-edit-it] A generated URL skin is a cached signed texture. Upload the revised PNG and select the new result. `/skin update` refreshes account skin data. ## Can I use a custom cape image? [#can-i-use-a-custom-cape-image] The website supports selected existing capes through its generation route. It does not accept arbitrary cape PNGs or grant account ownership. Read [cape support](/docs/features/capes). ## Does a green status mean all services work? [#does-a-green-status-mean-all-services-work] No. `/sr status` checks account UUID and profile services. MineSkin, website uploads, recommendations, and database access need their own checks. ## Where is the full reference? [#where-is-the-full-reference] Use [commands and permissions](/docs/configuration/commands-permissions), [configuration](/docs/configuration/options), and [placeholders](/docs/integrations/placeholderapi). ## What do I send to support? [#what-do-i-send-to-support] Send the setup, exact command, full error, diagnostic report, and recent log. Use [the support checklist](/docs/troubleshooting/debugging). # Collect diagnostics for support URL: /docs/troubleshooting/debugging SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Capture the setup, a diagnostic report, and the log around a failed command. A useful report lets another person reproduce the same result. Collect evidence from the instance where the failure occurs. ## Record the reproduction [#record-the-reproduction] Include: * SkinsRestorer, server/proxy, Minecraft, and Java versions. * Standalone or proxy setup, including the affected backend. * The exact command or API operation. * The complete error and expected result. * Whether reconnecting or switching servers changes the result. * Relevant plugins, mods, and storage type. ## Create a diagnostic report [#create-a-diagnostic-report] Run `/sr dump` from the affected instance's console. The command uploads a diagnostic report and returns a link. The report contains configuration, platform and plugin information, and environment details. The implementation excludes database configuration and the MineSkin API key. It does not include your recent console log. Review the report before sharing it. Other configuration or environment details can identify your setup. Do not publish unrelated credentials. ## Capture recent logs [#capture-recent-logs] 1. Enable `dev.debug: true` in the active configuration. 2. Run `/sr reload`, or restart if reload is unavailable. 3. Reproduce the problem once. 4. Copy the log from before the command through the full error. 5. Set `dev.debug` back to `false`. 6. Apply the configuration change again. Include the full exception, rather than the final line alone. For a startup error, include the startup log too. ## Ask for help [#ask-for-help] Use [SkinsRestorer support](/discord) with the report link, recent log, and reproduction. For a reproducible bug, open an [issue](https://github.com/SkinsRestorer/SkinsRestorer/issues). For a documentation correction, use the page's GitHub edit link or feedback form. State the page, the step, and the result that differs. # Fix service connections URL: /docs/troubleshooting/firewall SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Diagnose DNS, HTTPS, rate limits, and blocked outbound requests. A skin lookup can fail because of DNS, TLS, blocked HTTPS, an upstream error, or rate limits. Record the actual error before changing firewall rules. ## Narrow down the service [#narrow-down-the-service] 1. Run `/sr status` on the affected instance. 2. Try one known player name. 3. Try one valid skin URL if URL generation is the problem. 4. Save the matching console error. `/sr status` checks account UUID and profile services. It does not check every MineSkin route, recommendations, website uploads, or your database. If account names work but URLs fail, investigate the URL generation service and key. A green status result does not prove URL generation works. ## Check local configuration [#check-local-configuration] Keep `advanced.noConnections: false` for normal online operation. A true value prevents new external lookups, URL generation, and update checks. Check the machine's clock and Java trust store if the error concerns TLS. Do not disable certificate validation to hide a TLS problem. ## Outbound access [#outbound-access] The server needs DNS resolution and outbound HTTPS on port 443. Allow response traffic for established connections. Skin services do not need a new inbound server port. Use [the network reference](/docs/reference/network) to identify the host for the failed feature. API hosts and download redirects can change between releases. Ask the host to check connections from the actual Minecraft server environment. A successful request from your laptop does not prove the server has access. ## Rate limits [#rate-limits] Wait before repeated attempts. Keep normal cache durations. Lowering `storage.skinExpiresAfter` or `storage.uuidExpiresAfter` increases requests. `api.mojangBatchWindowSeconds` controls Mojang batching. It does not increase MineSkin upload limits. ## Protect proxy backends [#protect-proxy-backends] Backend protection is a separate inbound rule. Permit connections only from your proxy or trusted network. Legacy forwarding cannot authenticate an arbitrary direct connection. Use [PaperMC's backend security guide](https://docs.papermc.io/velocity/security/). Keep authentication on the public proxy consistent with your server policy. ## Next [#next] Read [MineSkin integration](/docs/integrations/mineskin) for URL generation errors. If the cause remains unclear, collect [support diagnostics](/docs/troubleshooting/debugging). # Isolate plugin and platform conflicts URL: /docs/troubleshooting/incompatibility-list SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Find which profile-changing plugin, mod, or server fork causes a problem. Plugins that change profiles, nicknames, tab lists, login state, or world state can replace skin data. A plugin name alone does not prove a conflict across all versions. ## Reproduce on a separate server [#reproduce-on-a-separate-server] 1. Back up the configuration and data. 2. Create a test server with the same Minecraft version. 3. Install only SkinsRestorer on an upstream supported platform. 4. Apply a known skin and reconnect. 5. Add one suspected plugin or mod. 6. Repeat the same skin check. 7. Continue until the problem returns. Keep the tested versions in your report. Do not remove plugins from a live server just to run this check. ## Common overlap [#common-overlap] * A skin plugin or script can apply another texture after SkinsRestorer. * A login plugin can restore an account profile after a custom selection. * A nickname or tab plugin can replace the visible player profile. * A client skin mod can override only that client's appearance. Inspect the competing integration's current configuration. For example, a login integration that forwards its own skin can conflict with server-selected skins. ## Forks and hybrid servers [#forks-and-hybrid-servers] A fork or hybrid mod/plugin server can alter profile APIs and refresh behavior. Reproduce on upstream Paper, Spigot, or the matching mod platform before you report a SkinsRestorer bug. Do not assume a historical incompatibility list applies to every current release. Report exact versions and a minimal reproduction. ## Next [#next] Use [launcher troubleshooting](/docs/troubleshooting/launcher-issues) for client-only differences. Include the reproduction and [diagnostics](/docs/troubleshooting/debugging) in a server-side report. # Fix a problem URL: /docs/troubleshooting SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Start with the symptom, then narrow down the cause. Choose the result that you actually see. Changing several configuration values at once makes the cause harder to find. ## Choose your symptom [#choose-your-symptom] | Symptom | Guide | | ------------------------------------------------------------ | ---------------------------------------------------------------------- | | Command succeeds, skin stays unchanged | [No visible skin](/docs/troubleshooting/no-skin) | | Command is denied | [Permission denied](/docs/troubleshooting/permissions) | | Skin disappears after a join, world change, or server switch | [Skin resets](/docs/troubleshooting/skin-resets) | | Backend warns about proxy mode or an unavailable API | [Proxy mode and backend API](/docs/troubleshooting/proxy-mode) | | Account skin or URL cannot load | [Service connections](/docs/troubleshooting/firewall) | | Upload or generation fails | [Upload problems](/docs/troubleshooting/uploads) | | Only one client sees the wrong skin | [Client and launcher overrides](/docs/troubleshooting/launcher-issues) | | A plugin, mod, or fork changes the result | [Conflicts](/docs/troubleshooting/incompatibility-list) | For quick answers, read [common questions](/docs/troubleshooting/common-issues). If these checks do not explain the problem, collect [diagnostics for support](/docs/troubleshooting/debugging). ## Report useful evidence [#report-useful-evidence] A useful report includes the exact command, full error, versions, setup, and the result after reconnecting. A screenshot of an unchanged skin alone does not identify the failed step. # Client and launcher skin overrides URL: /docs/troubleshooting/launcher-issues SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Diagnose a skin that looks wrong on one client only. A client mod or launcher skin system can replace the skin sent by the server. SkinsRestorer cannot detect which launcher a player uses. ## Compare clients [#compare-clients] 1. Apply a known skin with `/skin set xknat`. 2. Ask another player to check your appearance. 3. Join with an unmodified Java client. 4. Compare the results. If the unmodified client shows the correct skin, the server's skin property works. Inspect the affected client's mods and skin-system configuration. ## Remove the override [#remove-the-override] Disable custom skin or cape replacements in the affected client. Choose official/server-provided skins if the client offers that option. Restart the client and reconnect. Exact controls depend on the launcher and version. Use the launcher's current instructions instead of an old screenshot or video. Minecraft's Skin Customization controls only show or hide outer-layer parts. They do not choose a different server skin. ## About the launcher warning [#about-the-launcher-warning] The offline-mode warning is general advice. It does not identify your launcher. `/skin notification ignore-cracked-client` hides that warning for your player. Hiding the warning does not fix a client override. ## If all clients look wrong [#if-all-clients-look-wrong] Return to [no visible skin](/docs/troubleshooting/no-skin). Collect [diagnostics](/docs/troubleshooting/debugging) if the server-side application fails. # A skin change is not visible URL: /docs/troubleshooting/no-skin SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Separate fetching, profile application, and client rendering problems. Use this guide when a command reports success but the player still looks unchanged. ## Compare two views [#compare-two-views] 1. Run `/skin set xknat` with a Java client. 2. Ask another player to check the result. 3. Disconnect and join again. 4. Compare both views again. If another player sees the new skin, the server applied it. Inspect the affected client's [skin mods and launcher configuration](/docs/troubleshooting/launcher-issues). ## Inspect the selected data [#inspect-the-selected-data] Run `/sr info player ` on the instance that owns storage. Inspect the texture and selected skin. On a network, use the proxy console for ordinary administrative commands. If a texture cannot load, read [service connections](/docs/troubleshooting/firewall). If the stored selection is correct, continue with profile application. ## Check the application path [#check-the-application-path] * **Proxy:** Check forwarding and install SkinsRestorer on every backend. Use [proxy troubleshooting](/docs/troubleshooting/proxy-mode). * **Join only:** Inspect `advanced.disableOnJoinSkins` and online-mode behavior. Use [skin resets](/docs/troubleshooting/skin-resets). * **Resource pack:** Keep `server.resourcePackFix` enabled unless another integration handles profile refresh. * **Specific plugin or world:** Reproduce without competing profile plugins on a separate test server. Do not enable `advanced.teleportRefresh` as a first fix. It teleports players far away and back during refresh. ## Still unchanged [#still-unchanged] Collect a [diagnostic report and recent log](/docs/troubleshooting/debugging), including whose client sees the problem and whether reconnecting changes it. # A command is denied URL: /docs/troubleshooting/permissions SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Find the effective permission and the platform that owns the command. A permission error is different from a network error. `/sr status` cannot diagnose a missing command permission. ## Find the permission [#find-the-permission] 1. Read the complete error message. 2. Find the command in the [command reference](/docs/configuration/commands-permissions). 3. Inspect the player's effective permission with your permission manager. 4. Check parent grants, explicit denials, and server-specific contexts. For a skin URL, inspect `skinsrestorer.command.set.url`. For history, inspect `skinsrestorer.command.undo`. For the menu, inspect `skinsrestorer.command.gui`. ## Check the correct instance [#check-the-correct-instance] On a network, a backend permission grant can leave a proxy command denied. Apply permissions on the proxy when the proxy owns `/skin`. A server listed in `proxy.notAllowedCommandServers.list` can block commands independently of permissions. The default block list contains `auth`. ## Check additional restrictions [#check-additional-restrictions] * Per-skin access needs `skinsrestorer.skin.` when enabled. * An allowed command does not bypass a disabled skin or URL restriction. * A cooldown is a timing restriction, not a missing permission. * A disabled command needs configuration and a restart, not another grant. ## Check the fix [#check-the-fix] Use a regular player account. Run one allowed command and one denied command. Operator access or broad wildcards can hide an incorrect group configuration. Read [player access](/docs/configuration/player-access) to design the grants, or collect [diagnostics](/docs/troubleshooting/debugging) if the effective permission and command result disagree. # Proxy mode and the backend API URL: /docs/troubleshooting/proxy-mode SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Resolve mode warnings without adding an unnecessary database. A backend in proxy mode receives skins from the proxy. This is separate from exposing the Java API to plugins on that backend. ## Ordinary proxy-managed skins [#ordinary-proxy-managed-skins] Install SkinsRestorer on the proxy and every backend. Configure profile forwarding. Leave `server.proxyMode.detection` at `AUTO` on each backend. You do not need MySQL or PostgreSQL just because you have multiple backends. The proxy can own file storage and forward skins normally. If backend plugins do not call the API, you can disable backend API access: ```yaml title="Backend config.yml (SkinsRestorer excerpt)" server: proxyMode: detection: AUTO api: false ``` Restart the backend, then complete the [server-switch check](/docs/installation/quick-start). ## A backend plugin needs the API [#a-backend-plugin-needs-the-api] Set `server.proxyMode.api: true`. Configure the proxy and each API-enabled backend with the same MySQL or PostgreSQL database and table prefix. File storage does not support this backend API mode. The provider can remain unavailable even though ordinary forwarded skins work. Follow [the backend API guide](/docs/development/proxy-api), then inspect database initialization logs. ## Automatic detection fails [#automatic-detection-fails] First correct the platform's forwarding configuration. If detection still fails on a known proxy backend, set `server.proxyMode.detection: ENABLED` there and restart. Use `DISABLED` only for a genuinely standalone server or an intentional independent installation. Forcing a backend into standalone mode can produce competing skin behavior. ## Where to run diagnostics [#where-to-run-diagnostics] Proxy-mode backends provide `/sr status` and `/sr dump` for local diagnostics. Run storage administration and normal skin commands on the proxy. For forwarding setup, use [Velocity](/docs/installation/velocity) or [BungeeCord](/docs/installation/bungeecord). For the architecture, read [proxy ownership](/docs/concepts/proxy). # A skin resets after joining or switching URL: /docs/troubleshooting/skin-resets SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Check persistence, join behavior, resource packs, and profile forwarding. The event that resets the skin is useful evidence. Record whether it happens on reconnect, backend switch, world change, or resource-pack load. ## Check persistence first [#check-persistence-first] 1. Select a skin with `/skin set xknat`. 2. Inspect `/sr info player ` on the storage owner. 3. Reconnect. 4. Inspect the player record again. If an integration only calls `applySkin(player, property)`, it changes the current appearance without saving the selection. Read [persistent and temporary changes](/docs/development/storage). ## After a reconnect [#after-a-reconnect] Inspect `advanced.disableOnJoinSkins`. It prevents automatic application on join when enabled. On an online-mode server, `login.alwaysApplyPremium` controls application of stored skins to authenticated account players. If that is your intended policy, enable it and repeat the check. Default skin rules and saved selections also affect the result. `/skin clear` deliberately removes the saved selection. ## After a backend switch [#after-a-backend-switch] Check the proxy's selected skin and every backend's forwarding configuration. Do not let each backend independently own skin commands and player selections. The same player's UUID must remain consistent across the proxy and backends. Shared database configuration cannot fix incorrect forwarding. ## After a resource pack or world change [#after-a-resource-pack-or-world-change] Keep `server.resourcePackFix` enabled unless another integration handles the refresh. Check plugins that replace profiles, nicknames, or world state. Reproduce on a separate server with only SkinsRestorer. Then add the suspected plugins one at a time. ## Next [#next] Use [proxy troubleshooting](/docs/troubleshooting/proxy-mode) for network-only resets, or [conflict isolation](/docs/troubleshooting/incompatibility-list) for plugin-specific resets. # An upload or generated command fails URL: /docs/troubleshooting/uploads SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Separate image problems, generation queues, and server command failures. The website generates a command. Your server then runs that command. Identify which stage fails before you retry. ## The website rejects the file [#the-website-rejects-the-file] Use a standard PNG skin template. The website's file limit is 5 MB. A screenshot, JPEG, or HD image is not a standard skin template. If the preview shows arm gaps, switch between classic and slim. Read [the model guide](/docs/features/skin-design). ## Generation fails or waits [#generation-fails-or-waits] 1. Read the error shown on the page. 2. Wait for an active queue job to finish. 3. Check your API key if the error concerns authorization. 4. Check the available cape list if the error concerns cape access. A selected cape in **Axolotl** mode uses the proxy route. Plain uploads and **Official** mode use MineSkin directly. These paths can fail independently. Do not repeatedly submit the same file while a job is pending. ## The generated command fails [#the-generated-command-fails] Keep the URL quoted and the generated model value intact. An opaque `skinsrestorer-axolotl://` result is valid command input, rather than a browser link. Run a `/skin url` result in game chat for your own player. A `/sr createcustom` result needs administrative access on the server or proxy that owns storage. It creates a named skin, rather than selecting it for a player. Inspect `skinsrestorer.command.set.url` and [URL restrictions](/docs/configuration/restrict-skins). If generation succeeded but the server cannot load the result, inspect [service connections](/docs/troubleshooting/firewall). ## Report a problem [#report-a-problem] Include the stage, error text, model, whether you selected a cape, and whether you used an API key. Do not include the key itself. Use [support diagnostics](/docs/troubleshooting/debugging) for a server-side error. # Advanced behavior URL: /docs/reference/advanced SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for advanced behavior. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/troubleshooting/no-skin). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | ---------------------------------- | ------- | ------- | -------------------------------------------------------------------------------- | | `advanced.disableOnJoinSkins` | boolean | `false` | Prevent automatic join application. | | `advanced.enablePaperJoinListener` | boolean | `true` | Use the Paper join integration and resource-pack refresh handling. | | `advanced.noConnections` | boolean | `false` | Disable external services, URL generation, account requests, and update checks. | | `advanced.playerHeadChatObjects` | boolean | `false` | Use player-head components in messages when supported. | | `advanced.teleportRefresh` | boolean | `false` | Teleport away and back during refresh. Use only for a diagnosed refresh problem. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [AdvancedConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/AdvancedConfig.java). # Command behavior URL: /docs/reference/commands SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for command behavior. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/configuration/player-access). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- | | `commands.customHelp.enabled` | boolean | `false` | Use the custom skin help message. | | `commands.customHelp.message` | string list | `["Skin plugin Help", "---------------------", "/skin set - Set your skin"]` | MiniMessage lines for custom help. | | `commands.disableGUICommand` | boolean | `false` | Skip /skins registration. Restart required. | | `commands.disableSkinCommand` | boolean | `false` | Skip /skin registration. Restart required. | | `commands.disableSkullCommand` | boolean | `false` | Skip /skull registration. Restart required. | | `commands.disabledSkins.enabled` | boolean | `false` | Block the configured skin names. | | `commands.disabledSkins.list` | string list | `["steve", "owner"]` | Blocked names. The bypassdisabled permission bypasses this restriction. | | `commands.forceDefaultPermissions` | boolean | `true` | Grant fallback player permissions on platforms without default permission support. | | `commands.maxFavouriteLength` | integer | `180` | Maximum favorites per player. Zero disables favorites. | | `commands.maxHistoryLength` | integer | `36` | Maximum saved history entries per player. Zero disables history. | | `commands.perSkinPermissions` | boolean | `false` | Require a `skinsrestorer.skin.` permission. | | `commands.perSkinPermissionsConsent` | string | `""` | Required consent text: I will follow the rules. | | `commands.restrictSkinUrls.enabled` | boolean | `false` | Restrict skin URLs to the configured list. | | `commands.restrictSkinUrls.list` | string list | `["https://i.imgur.com", "http://i.imgur.com", "https://storage.googleapis.com", "http://storage.googleapis.com", "https://cdn.discordapp.com", "http://cdn.discordapp.com", "https://textures.minecraft.net", "http://textures.minecraft.net"]` | Allowed URL prefixes for restricted URL selection. | | `commands.skinChangeCooldown` | integer | `30` | Seconds between successful skin changes. Zero disables the cooldown. | | `commands.skinErrorCooldown` | integer | `5` | Seconds of cooldown after a skin error. | | `commands.skullErrorCooldown` | integer | `5` | Seconds of cooldown after a skull error. | | `commands.skullGetCooldown` | integer | `30` | Seconds between skull requests. Zero disables the cooldown. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [CommandConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/CommandConfig.java). # Database configuration URL: /docs/reference/database SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for database configuration. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/configuration/database). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | ---------------------------- | ------- | ------------------------------------ | ------------------------------------------------------------------------------------- | | `database.connectionOptions` | string | `"sslMode=trust&serverTimezone=UTC"` | Driver connection options. Choose values appropriate for the database and TLS policy. | | `database.database` | string | `"db"` | SQL database name. | | `database.host` | string | `"localhost"` | SQL server hostname or address. | | `database.maxPoolSize` | integer | `10` | Maximum pooled connections per instance, from 1 to 1000. | | `database.password` | string | `"pass"` | SQL login password. Replace the default before use. | | `database.port` | integer | `3306` | SQL server port, from 1 to 65535. PostgreSQL usually uses 5432. | | `database.tablePrefix` | string | `"sr_"` | Prefix for SkinsRestorer tables. Match it across shared instances. | | `database.type` | enum | `"FILE"` | Storage backend: FILE, MYSQL, or POSTGRESQL. Restart required. | | `database.username` | string | `"root"` | SQL login username. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [DatabaseConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/DatabaseConfig.java). # Documentation sources and maintenance URL: /docs/reference/documentation SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Understand the version boundary and keep these guides accurate. These pages target **SkinsRestorer 15.12.6**, reviewed on **October 1, 2026**. Website workflows describe this repository's upload and generator implementations. ## Source of truth [#source-of-truth] | Subject | Primary source | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | Configuration keys and defaults | [Release configuration classes](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config) | | Commands and permissions | [Release command definitions](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/shared/src/main/java/net/skinsrestorer/shared/commands) | | API signatures and exceptions | [Release public API](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/api/src/main/java/net/skinsrestorer/api) | | Fabric requirements | [Release metadata](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/mod/fabric/src/main/resources/fabric.mod.json) | | Velocity forwarding | [PaperMC instructions](https://docs.papermc.io/velocity/player-information-forwarding/) | | DiscordSRV avatar configuration | [DiscordSRV reference](https://docs.discordsrv.com/config/) | | MineSkin limits and grants | [MineSkin documentation](https://docs.mineskin.org/) | Do not replace release facts with an unreviewed development branch. External platform configuration and service limits need their own version check. ## Documentation design [#documentation-design] The structure separates guided learning, task procedures, exact reference, and explanations. It follows [Diátaxis](https://diataxis.fr/) and uses [Fumadocs](https://www.fumadocs.dev/docs/ui) for navigation, code blocks, and search. A procedure needs prerequisites, working steps, an expected result, and a useful failure branch. Reference tables need exact names and a source version. ## Contribute a correction [#contribute-a-correction] Use the page's GitHub link to edit its MDX source. Include the affected release and a reproducible reason for a technical correction. For a broken step, state what you tried and the actual result. For a new feature, add the procedure and reference together. ## Release checklist [#release-checklist] Maintainers can find the source inventory and local validation instructions in the repository's `documentation/README.md`. For each release, compare source declarations, update the inventory and affected pages, compile the complete Java example, and build the website. Then inspect representative installation, upload, proxy, and API pages. Treat page feedback as a correction queue. Record the URL, release, reported result, and resolution in an issue or documentation change. # Skin menu configuration URL: /docs/reference/gui SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for skin menu configuration. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/configuration/skin-menu). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | ---------------------------------- | ----------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------- | | `gui.custom.enabled` | boolean | `true` | Show the custom category. | | `gui.custom.index` | integer | `0` | Category order. Smaller indexes appear first. | | `gui.custom.list` | string list | `["xknat", "pistonmaster"]` | Allowed custom entries when onlyShowList is true. | | `gui.custom.onlyShowList` | boolean | `false` | Show only entries from this category's list. | | `gui.notUnlockedSkin` | string | `"c10591e6909e6a281b371836e462d67a2c78fa0952e910f32b41a26c48c1757c"` | Texture hash for a locked menu entry. | | `gui.players.enabled` | boolean | `false` | Show the players category. | | `gui.players.index` | integer | `1` | Category order. Smaller indexes appear first. | | `gui.players.list` | string list | `["7dcfc130-344a-4719-9fbe-3176bc2075c6", "b1ae0778-4817-436c-96a3-a72c67cda060"]` | Allowed players entries when onlyShowList is true. | | `gui.players.onlyShowList` | boolean | `false` | Show only entries from this category's list. | | `gui.recommendations.enabled` | boolean | `true` | Show the recommendations category. | | `gui.recommendations.index` | integer | `2` | Category order. Smaller indexes appear first. | | `gui.recommendations.list` | string list | `["vampire", "space-suit"]` | Allowed recommendations entries when onlyShowList is true. | | `gui.recommendations.onlyShowList` | boolean | `false` | Show only entries from this category's list. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [GUIConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/GUIConfig.java). # Reference URL: /docs/reference SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Look up commands, permissions, configuration, placeholders, and network hosts. Use these pages when you know the task and need an exact name, value, or syntax. * [Commands and permissions](/docs/configuration/commands-permissions). * [Configuration sections](/docs/configuration/options). * [PlaceholderAPI values](/docs/integrations/placeholderapi). * [Network hosts and services](/docs/reference/network). * [Platform requirements](/docs/installation/requirements). * [Documentation sources and maintenance](/docs/reference/documentation). For step-by-step instructions, start with [installation](/docs/installation) or [server management](/docs/configuration). # Messages and diagnostics URL: /docs/reference/messages SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for messages and diagnostics. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/configuration/locale-translations). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | -------------------------- | ------- | ---------------- | -------------------------------------------------------------- | | `dev.debug` | boolean | `false` | Record additional diagnostic details in the log. | | `messages.consoleLocale` | locale | `"en"` | Console locale. | | `messages.dateFormat` | string | `"dd MMMM yyyy"` | Java date format for message timestamps. | | `messages.disablePrefix` | boolean | `false` | Omit the message prefix. | | `messages.locale` | locale | `"en"` | Default player locale. Language-country codes use underscores. | | `messages.perIssuerLocale` | boolean | `true` | Use each player's client locale when a translation exists. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [DevConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/DevConfig.java). * [MessageConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/MessageConfig.java). # Network hosts and services URL: /docs/reference/network SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Identify outbound HTTPS requests by the feature that uses them. SkinsRestorer uses outbound connections. It does not require a new inbound port for skin APIs. Permit DNS through your configured resolver and HTTPS response traffic for established connections. ## Feature-specific hosts [#feature-specific-hosts] | Feature | Host | Notes | | --------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------- | | Account UUID lookup | `api.mojang.com`, `api.minecraftservices.com`, `eclipse.skinsrestorer.net` | Account lookup and fallback routes | | Account profile lookup | `sessionserver.mojang.com`, `eclipse.skinsrestorer.net` | Signed account textures | | URL skin generation | `api.mineskin.org` | Server generation and website queue requests | | Website and cape-aware generation | `axolotl.skinsrestorer.net` | Website route and generated URL resolution | | Recommended skins | `cool-skins.skinsrestorer.net` | Random skins and recommended menu entries | | Diagnostic upload | `bytebin.lucko.me` | `/sr dump` report upload | | Update checks and downloads | `api.github.com`, `github.com` | Downloads can redirect to GitHub asset hosts | | Optional Ely.by account source | `account.ely.by`, `skinsystem.ely.by` | Only with `api.elyByEnabled` | | Client texture download | `textures.minecraft.net` | Java clients fetch the skin image | HTTPS uses port 443. DNS transport follows your host's resolver configuration. Do not assume one static IP per API host. The exact request list depends on enabled features and the release. GitHub downloads can involve additional redirected asset hosts. Inspect the failed request instead of opening every domain indiscriminately. ## Status check scope [#status-check-scope] `/sr status` exercises account UUID and profile services. It does not check MineSkin, Axolotl uploads, recommendations, or database access. The website's MineSkin availability indicator also does not prove every cape or upload route works. ## Sources [#sources] * [Release connection implementations](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/shared/src/main/java/net/skinsrestorer/shared/connections). * [Release update implementations](https://github.com/SkinsRestorer/SkinsRestorer/tree/15.12.6/shared/src/main/java/net/skinsrestorer/shared/update). * [Website generation implementation](https://github.com/SkinsRestorer/skinsrestorer.net/blob/main/src/lib/mineskin.ts). For connection diagnosis and backend protection, use [the firewall guide](/docs/troubleshooting/firewall). # Server, login, and proxy behavior URL: /docs/reference/server SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for server, login, and proxy behavior. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/troubleshooting/proxy-mode). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | ------------------------------------------------------- | ----------- | ------------------------------- | ---------------------------------------------------------------------------------- | | `login.alwaysApplyPremium` | boolean | `false` | Apply stored skins to account players on online-mode joins. | | `login.noSkinIfLoginCanceled` | boolean | `true` | Skip skin processing for a canceled login. | | `login.offlineModeWarning.enabled` | boolean | `true` | Show the general client skin-override warning to offline-mode players. | | `proxy.notAllowedCommandServers.allowList` | boolean | `false` | False blocks listed backends. True allows only listed backends. | | `proxy.notAllowedCommandServers.enabled` | boolean | `true` | Restrict commands by backend name. | | `proxy.notAllowedCommandServers.ifNoServerBlockCommand` | boolean | `true` | Block commands before a player joins a backend. | | `proxy.notAllowedCommandServers.list` | string list | `["auth"]` | Backend names for the command restriction. | | `server.dismountPassengersOnSkinUpdate` | boolean | `false` | Dismount passengers from the player before refresh. | | `server.dismountPlayerOnSkinUpdate` | boolean | `true` | Dismount the player before refresh to avoid mount synchronization problems. | | `server.proxyMode.api` | boolean | `true` | Expose the API on a proxy backend. Requires shared SQL storage. | | `server.proxyMode.detection` | enum | `"AUTO"` | AUTO detects the proxy. Other values: ENABLED and DISABLED. Restart after changes. | | `server.remountPlayerOnSkinUpdate` | boolean | `true` | Remount afterward. Requires dismountPlayerOnSkinUpdate. | | `server.resourcePackFix` | boolean | `true` | Reapply skins after resource-pack changes. | | `server.sound.enabled` | boolean | `true` | Play the skin-change sound. | | `server.sound.value` | string | `"ENTITY_PLAYER_TELEPORT, 0.7"` | Sound name and playback parameters. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [LoginConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/LoginConfig.java). * [ProxyConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/ProxyConfig.java). * [ServerConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/ServerConfig.java). # External services URL: /docs/reference/services SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for external services. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/integrations/mineskin). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | ------------------------------ | ------- | ------- | ------------------------------------------------------------------------------ | | `api.elyByEnabled` | boolean | `false` | Use Ely.by account skins instead of Mojang account skins. | | `api.fetchRecommendedSkins` | boolean | `true` | Load recommendations for random skins and the menu. | | `api.mineskinAPIKey` | string | `"key"` | Optional server-side MineSkin key. Keep it private. | | `api.mineskinSecretSkins` | boolean | `false` | Request unlisted generated skins. Texture URLs remain accessible. | | `api.mojangBatchWindowSeconds` | integer | `1` | Seconds before an account lookup batch ends. A batch also ends at 10 requests. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [APIConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/APIConfig.java). # Storage and caches URL: /docs/reference/storage SkinsRestorer: 15.12.6 Applies to: All platforms Reviewed: 2026-10-01 Exact keys, types, and defaults for storage and caches. These values describe SkinsRestorer 15.12.6. Keys are case-sensitive. Defaults describe a new installation, not your existing configuration. For a task-based guide, read [the related procedure](/docs/configuration/default-skins). ## Keys and defaults [#keys-and-defaults] | Key | Type | Default | Meaning | | -------------------------------------- | ----------- | --------------------------------------- | --------------------------------------------------------------------- | | `storage.defaultSkins.applyForPremium` | boolean | `false` | Apply default skins to account players without a saved selection too. | | `storage.defaultSkins.enabled` | boolean | `false` | Use the configured fallback list. | | `storage.defaultSkins.list` | string list | `["xknat", "pistonmaster", ""]` | Choose a listed name randomly. `` uses recommendations. | | `storage.disallowAutoUpdateSkin` | boolean | `false` | Require `/skin update` for newer cached account skin data. | | `storage.skinExpiresAfter` | integer | `15` | Skin cache lifetime in minutes. Zero requests fresh data each time. | | `storage.uuidExpiresAfter` | integer | `60` | UUID cache lifetime in minutes. Zero requests fresh data each time. | ## Source and reload behavior [#source-and-reload-behavior] Edit the existing section in the active `config.yml`. Use `/sr reload` for ordinary behavior changes. Restart after storage, proxy detection, or command registration changes. * [StorageConfig.java](https://github.com/SkinsRestorer/SkinsRestorer/blob/15.12.6/shared/src/main/java/net/skinsrestorer/shared/config/StorageConfig.java).