nineMinecraft is a joke site.
nineMinecraft is in no way affiliated with Modrinth or 9minecraft. (And frankly, who wants to be affiliated with the latter?)
FluxBans

FluxBans

Plugin

FluxBans is a modern minecraft punishments plugin. It has a built in website. It has an appeals system, ban, kick, mute and temp punishments and much more!

Server LibraryManagementSocialTechnologyUtility

41 downloads
1 follower

FluxBans

The punishment management plugin your network's been waiting for.

Java 8+ Servers Players Downloads


Running a server means dealing with griefers, cheaters, toxic players and the occasional ban evader. You need a punishment system that keeps up, works across every platform you're running, and doesn't need babysitting. FluxBans handles bans, mutes, kicks and warnings across Spigot, Paper, Folia, BungeeCord, Velocity and NeoForge from a single shared database. It ships with an embedded web dashboard, a full ban appeals system, Discord webhooks and a REST API — no paid tier, no feature gates, no abandoned repo.


Platform support

Platform JAR Supported versions
Spigot / Paper FluxBans-Bukkit.jar 1.8.8 to 1.21.x
Folia FluxBans-Folia.jar Latest stable
BungeeCord FluxBans-BungeeCord.jar Latest stable
Velocity FluxBans-Velocity.jar 3.x
NeoForge FluxBans-Forge.jar 1.21.1

Every JAR is self-contained. Point them all at the same database and they stay in sync automatically. Ban someone on BungeeCord and they're blocked on every backend before they can reconnect.


How it compares

Feature FluxBans LiteBans LibertyBans AdvancedBan BanManager CMI
Price Free $15 Free Free Free $15
Actively maintained Yes Yes Yes No Yes Yes
Spigot / Paper Yes Yes Yes Yes Yes Yes
BungeeCord Yes Yes Yes No Yes No
Velocity Yes Yes Yes No Yes No
Folia Yes No No No No No
NeoForge Yes No No No No No
Embedded web dashboard Yes Yes No No No No
Built-in appeals system Yes No No No No No
Discord webhooks Yes Yes No No No Yes
Generic HTTP webhooks Yes No No No No No
REST API Yes No No No No No
IP / CIDR banning Yes Yes Yes No Yes Yes
Auto escalating warnings Yes No No Yes No Yes
LuckPerms weight exemptions Yes No No No No No
ProtectCord support Yes No No No No No
Config hot reload Yes No No No No Yes
SQLite support Yes Yes Yes No Yes No
MySQL / MariaDB support Yes Yes Yes No Yes Yes
PostgreSQL support Yes Yes Yes No No No
Import from other plugins Yes No Yes No No No

Bans

Banning blocks a player from rejoining for the duration you set. The check happens at connection time so they never get past the login screen.

/ban <player> [reason] [-s]
/tempban <player> <duration> [reason] [-s]
/banip <player|ip> [reason] [-s]
/unban <player|uuid>
/unbanip <ip>

Temp bans take durations like 7d, 12h, 30m or combinations like 1d12h. You can ban by username, UUID, IP address or an entire CIDR subnet. The -s flag makes the ban silent — see the silent mode section below.

Permission Description
fluxbans.ban Use /ban
fluxbans.ban.temp Use /tempban
fluxbans.ban.ip Use /banip and /unbanip
fluxbans.ban.silent Add the -s flag to ban commands
fluxbans.unban Use /unban
fluxbans.exempt.ban This player cannot be banned

Mutes

Muting prevents a player from sending chat messages and using any command you list under mute.blocked-commands in config.yml. The check runs on every chat event and blocked command so it can't be bypassed by using an alias.

/mute <player> [reason] [-s]
/tempmute <player> <duration> [reason] [-s]
/unmute <player>
Permission Description
fluxbans.mute Use /mute
fluxbans.mute.temp Use /tempmute
fluxbans.mute.silent Add the -s flag to mute commands
fluxbans.unmute Use /unmute
fluxbans.exempt.mute This player cannot be muted

Kicks

Kicks disconnect the player immediately. They can reconnect straight away unless they're also banned.

/kick <player> [reason] [-s]
Permission Description
fluxbans.kick Use /kick
fluxbans.kick.silent Add the -s flag
fluxbans.exempt.kick This player cannot be kicked

Warnings

Warnings accumulate and trigger automatic punishments when a player hits the thresholds you set in config.yml. By default that's a 1 hour mute at 3 warnings, a 1 day ban at 5, and a permanent ban at 10. You can change all of that to whatever your server policy is.

/warn <player> [reason] [-s]
/unwarn <id>
Permission Description
fluxbans.warn Use /warn
fluxbans.warn.remove Use /unwarn to remove a specific warning
fluxbans.warn.silent Add the -s flag
fluxbans.exempt.warn This player cannot be warned

Silent mode

Add -s to any punishment command and the broadcast that normally goes to all players is suppressed. Only staff members online with fluxbans.notify will see it in their chat. Useful when you don't want to tip off a ban evader's friends by announcing the ban publicly.


Preset reasons

Define shortcuts in reasons.yml so your staff don't have to type the same thing every time:

/ban Steve #hacking
/mute Dave #chat-spam

The # prefix triggers a preset lookup. Durations can be locked per preset so staff can't accidentally give someone a lighter punishment than your policy requires.


Information commands

/check <player> — pulls up a full snapshot of a player's current status: active ban, active mute, warning count, IP address and any linked alt accounts.

/history <player> — shows every punishment ever issued to a player, including expired and removed ones, with who issued them and when.

/alts <player> — shows every account that has ever connected from the same IP addresses as the target.

/dupeip <ip> — the reverse of alts. Give it an IP and see everyone who has used it.

/banlist [page] and /mutelist [page] — lists all currently active bans or mutes in chat, paginated.

Permission Description
fluxbans.check Use /check
fluxbans.history Use /history
fluxbans.alts Use /alts
fluxbans.dupeip Use /dupeip
fluxbans.banlist Use /banlist
fluxbans.mutelist Use /mutelist
fluxbans.seeip See full IP addresses in /check output

Exemptions and LuckPerms

Any player with fluxbans.exempt.<type> cannot be punished by staff who don't outrank them. When LuckPerms is installed, FluxBans uses weight-based exemption — a moderator with weight 50 can't ban a player with weight 100 even if they have fluxbans.ban. Senior staff always override junior staff. Works without LuckPerms too, it just falls back to permission-only checks.


Web dashboard

The dashboard is embedded directly in the JAR using NanoHTTPD. Nothing to install, no separate process. It starts when the plugin loads and is accessible at http://your-server-ip:8080 (configurable in web.yml).

Anyone can see the ban list, mute list and player history. Search and paginate through records, click through to a player profile showing their alt accounts, join history and everything ever issued against them.

Staff with the admin token can review and approve or deny appeals, manually lift punishments, write notes, and browse the full action log — all from the same panel.

Developers can use the REST API at /api/v1/ to pull data as JSON for their own integrations:

GET /api/v1/bans                 Paginated list of active bans
GET /api/v1/mutes                Paginated list of active mutes
GET /api/v1/player/:uuid         Full punishment history for a player
GET /api/v1/stats                Server-wide moderation statistics

HTTPS is supported if you provide a keystore in web.yml. Bind address, port, theme, branding and rate limits are all configurable.


Appeals system

Players appeal directly from the web. No Discord account, no forum, no third party service.

  1. Player visits /appeal on your web panel
  2. They enter their username and write their appeal (50 to 5,000 characters)
  3. FluxBans generates a unique private link — something like /appeal/a3f9c2e1 — so they can check back on the status
  4. A Discord webhook fires so your staff team knows straight away
  5. Staff go to /admin, read the appeal, and click Approve or Deny with an optional written response
  6. If approved, the punishment is removed from the database immediately. Player can rejoin, no command needed
  7. A second webhook fires confirming the outcome and the player's link updates to show the result

Rate limited to 3 submissions per hour per IP. Players with an open appeal can't submit another until it's resolved.


Webhooks

webhooks:
  # Discord webhook with rich embeds
  - url: "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN"
    type: discord
    enabled: true
    events:
      - ban
      - unban
      - mute
      - unmute
      - kick
      - warn
      - appeal_new
      - appeal_resolved
    skip-silent: true
    colors:
      ban: 15158332
      unban: 3066993
      mute: 15105570
      unmute: 3447003
      kick: 10181046
      warn: 16776960
      appeal_new: 3447003
      appeal_resolved: 3066993

  # Generic HTTP webhook with optional HMAC-SHA256 signing
  - url: "https://your-site.com/api/fluxbans-webhook"
    type: generic
    enabled: true
    events:
      - appeal_new
      - appeal_resolved
    secret: "your-hmac-secret"

Generic webhooks POST a JSON payload. If you set a secret, every request is signed with X-FluxBans-Signature: sha256=<hex> so your endpoint can verify it came from FluxBans.


Database support

Backend Notes
SQLite Bundled, zero setup
MySQL Recommended for networks
MariaDB Full support
PostgreSQL Full support

All backends use HikariCP connection pooling. The schema creates and migrates itself on startup.


Integrations

ProtectCord — enable with protectcord.enabled: true in config.yml and FluxBans will read the real player IP from ProtectCord metadata so IP bans work correctly through the proxy layer.

LuckPerms — auto-detected. Enables weight-based staff exemptions when present.

Vault — auto-detected. Pulls staff display names and prefixes into web UI records when present.


Migrating from another plugin

/fluxbans import litebans
/fluxbans import advancedban
/fluxbans import banmanager

Reads your existing database and maps everything across. Use --dry-run first to preview what will be imported before it touches anything.


Full default configuration

config.yml
# ─────────────────────────────────────────────────────────────
#  FluxBans — Main Configuration
#  Documentation: https://github.com/fluxbans/FluxBans/wiki
# ─────────────────────────────────────────────────────────────

# ── Database ──────────────────────────────────────────────────
database:
  # Backend type: sqlite | mysql | mariadb | postgresql
  type: sqlite

  # SQLite — file path relative to the plugin data folder
  file: fluxbans.db

  # MySQL / MariaDB / PostgreSQL connection settings
  host: localhost
  port: 3306
  name: fluxbans
  username: root
  password: ""

  # Optional additional JDBC properties (key: value)
  properties: {}

# ── General ───────────────────────────────────────────────────
general:
  # Server name shown in punishment records and the web UI
  server-name: "Survival"

  # Log all punishments to the console
  log-to-console: true

  # Broadcast a punishment to all online staff (fluxbans.notify permission)
  broadcast-to-staff: true

  # Broadcast a punishment to all online players
  broadcast-globally: true

  # How many entries to show per page in /history, /banlist etc.
  page-size: 10

  # Sync interval (seconds) — how often to fetch cross-server punishment
  # updates when using a shared MySQL/MariaDB/PostgreSQL database.
  # Set to 0 to disable (only needed for multi-server setups).
  sync-interval: 30

  # Hide IP addresses from /check output for players without fluxbans.seeip
  hide-ips: true

  # Enable IP banning in addition to UUID banning
  ip-banning: true

  # If true, banning a player by name also bans their current IP
  ban-ip-on-ban: false

# ── Exemption ─────────────────────────────────────────────────
exemptions:
  # Prevent staff from punishing players with a higher LuckPerms weight
  use-luckperms-weight: true

# ── ProtectCord ───────────────────────────────────────────────
protectcord:
  # Set to true when using ProtectCord on your BungeeCord / Velocity proxy.
  # FluxBans will use the real forwarded IP instead of the proxy IP.
  enabled: false

# ── Mute ──────────────────────────────────────────────────────
mute:
  # Commands blocked while a player is muted.
  blocked-commands:
    - /say
    - /me
    - /msg
    - /tell
    - /w
    - /r
    - /reply
    - /pm
    - /dm
    - /whisper

# ── Warnings ──────────────────────────────────────────────────
warnings:
  # Auto-punish a player when they reach certain warning thresholds.
  auto-punish:
    - count: 3
      action: mute
      duration: "1h"
      reason: "Accumulated {count} warnings"
    - count: 5
      action: ban
      duration: "1d"
      reason: "Accumulated {count} warnings"
    - count: 10
      action: ban
      duration: "perm"
      reason: "Accumulated {count} warnings — permanent ban"

# ── Date/time display format ──────────────────────────────────
date-format: "dd MMM yyyy HH:mm:ss"
timezone: "UTC"
messages.yml
# ─────────────────────────────────────────────────────────────
#  FluxBans — Messages Configuration
#  Colour codes: &0-9 &a-f &k-o &r
#  Hex colours (1.16+): &#RRGGBB
#  Placeholders vary by context — see the wiki for a full list.
# ─────────────────────────────────────────────────────────────

prefix: "&8[&cFluxBans&8] &r"

# ── Bans ──────────────────────────────────────────────────────
ban:
  default-reason: "You have been banned."
  temp-default-reason: "Temporarily banned."
  ip-default-reason: "IP banned."

  kick-message: |
    &c&lYou are banned from this server.
    &7Reason: &f{reason}
    &7Duration: &f{duration}
    &7Expires: &f{expires}
    &7Appeal at: &b{appeal-url}
    &7Ban ID: &f#{id}

  broadcast: "&c{operator} &7banned &c{player} &7» &f{reason} &7[{duration}]"
  broadcast-silent: "&c{operator} &7silently banned &c{player} &7» &f{reason} &7[{duration}]"
  notify: "{prefix}&7{operator} banned &c{player} &7» {reason} [{duration}]"
  ip-broadcast: "&c{operator} &7IP-banned &c{player} ({ip}) &7» &f{reason} &7[{duration}]"

  banned: "{prefix}&aSuccessfully banned &c{player}&a."
  already-banned: "{prefix}&c{player} &7is already banned."
  unbanned: "{prefix}&aSuccessfully unbanned &c{player}&a."
  not-banned: "{prefix}&c{player} &7is not banned."

# ── Mutes ─────────────────────────────────────────────────────
mute:
  default-reason: "Muted."
  temp-default-reason: "Temporarily muted."

  broadcast: "&c{operator} &7muted &c{player} &7» &f{reason} &7[{duration}]"
  broadcast-silent: "&c{operator} &7silently muted &c{player} &7» &f{reason} &7[{duration}]"
  notify: "{prefix}&7{operator} muted &c{player} &7» {reason} [{duration}]"

  muted: "{prefix}&aSuccessfully muted &c{player}&a."
  already-muted: "{prefix}&c{player} &7is already muted."
  unmuted: "{prefix}&aSuccessfully unmuted &c{player}&a."
  not-muted: "{prefix}&c{player} &7is not muted."

  chat-blocked: |
    {prefix}&cYou are muted.
    &7Reason: &f{reason}
    &7Expires: &f{expires}

# ── Kicks ─────────────────────────────────────────────────────
kick:
  default-reason: "Kicked."

  kick-message: |
    &c&lYou were kicked from the server.
    &7Reason: &f{reason}
    &7By: &f{operator}

  broadcast: "&c{operator} &7kicked &c{player} &7» &f{reason}"
  broadcast-silent: "&c{operator} &7silently kicked &c{player} &7» &f{reason}"
  notify: "{prefix}&7{operator} kicked &c{player} &7» {reason}"
  kicked: "{prefix}&aKicked &c{player}&a."

# ── Warnings ──────────────────────────────────────────────────
warn:
  default-reason: "Warned."

  broadcast: "&e{operator} &7warned &e{player} &7» &f{reason}"
  broadcast-silent: "&e{operator} &7silently warned &e{player} &7» &f{reason}"
  notify: "{prefix}&7{operator} warned &e{player} &7» {reason}"
  warned: "{prefix}&aWarned &e{player}&a."
  unwarned: "{prefix}&aRemoved warning #{id} from &e{player}&a."
  not-warned: "{prefix}&cWarning #{id} not found."

  received: |
    {prefix}&eYou have been warned by &c{operator}&e.
    &7Reason: &f{reason}
    &7Total active warnings: &c{count}

# ── History ───────────────────────────────────────────────────
history:
  header: "{prefix}&7Punishment history for &c{player} &7(page {page}/{pages}):"
  entry: " &8» &7[&c{type}&7] &f{reason} &7by &f{operator} &7on &f{date}"
  no-history: "{prefix}&7No punishment history found for &c{player}&7."

# ── Check ─────────────────────────────────────────────────────
check:
  header: "{prefix}&7Status for &c{player}&7:"
  banned: " &7Ban: &cYes &7(#{id}) — {reason} — expires {expires}"
  not-banned: " &7Ban: &aNone"
  muted: " &7Mute: &eYes &7(#{id}) — {reason} — expires {expires}"
  not-muted: " &7Mute: &aNone"
  warnings: " &7Warnings: &e{count} active"
  ip: " &7IP: &f{ip}"

# ── Banlist / Mutelist ────────────────────────────────────────
banlist:
  header: "{prefix}&7Active bans &7(page {page}/{pages}, total: {count}):"
  entry: " &8» &c{player} &7by &f{operator} &7— {reason} &7[{duration}]"
  empty: "{prefix}&7No active bans."

mutelist:
  header: "{prefix}&7Active mutes &7(page {page}/{pages}, total: {count}):"
  entry: " &8» &e{player} &7by &f{operator} &7— {reason} &7[{duration}]"
  empty: "{prefix}&7No active mutes."

# ── Alts ─────────────────────────────────────────────────────
alts:
  header: "{prefix}&7Alt accounts sharing IP with &c{player}&7:"
  entry: " &8» &c{name} &7(last seen: {date})"
  none: "{prefix}&7No alt accounts found for &c{player}&7."
  shared-ip: " &7Shared IP: &f{ip}"

# ── General errors ────────────────────────────────────────────
error:
  no-permission: "{prefix}&cYou do not have permission to do that."
  player-not-found: "{prefix}&cPlayer &f{player} &cnot found."
  console-only: "{prefix}&cThis command can only be run from the console."
  player-only: "{prefix}&cThis command can only be run by a player."
  invalid-duration: "{prefix}&cInvalid duration: &f{input}&c."
  player-exempt: "{prefix}&c{player} &7is exempt from this punishment."
  self-punish: "{prefix}&cYou cannot punish yourself."
  database-error: "{prefix}&cA database error occurred. Please check the console."
  usage: "{prefix}&cUsage: &f{usage}"
  unknown-command: "{prefix}&cUnknown command. Type &f/fluxbans help &cfor a list."

# ── FluxBans admin ────────────────────────────────────────────
admin:
  reloaded: "{prefix}&aConfiguration reloaded successfully."
  import-start: "{prefix}&7Starting import from &c{plugin}&7..."
  import-done: "{prefix}&aImport complete. &7Imported &c{count} &7records."
  import-failed: "{prefix}&cImport failed: &f{error}"

# ── Web appeal URL ────────────────────────────────────────────
appeal-url: "http://example.com:8080/appeal"
reasons.yml
# ─────────────────────────────────────────────────────────────
#  FluxBans — Preset Reasons
#
#  Staff can use these with: /ban <player> #hacking
#  The # prefix triggers a preset reason lookup.
#
#  Fields:
#    display  — reason text sent to the player and logged in DB
#    duration — optional locked duration (staff cannot override)
#    type     — optional: ban | mute | kick | warn
# ─────────────────────────────────────────────────────────────

hacking:
  display: "Hacking / Cheating"
  duration: "30d"
  type: ban

xray:
  display: "X-Ray / Resource pack abuse"
  duration: "14d"
  type: ban

chat-spam:
  display: "Chat spam"
  duration: "1h"
  type: mute

advertising:
  display: "Advertising other servers"
  duration: "7d"
  type: mute

hate-speech:
  display: "Hate speech / Discrimination"
  duration: "30d"
  type: mute

griefing:
  display: "Griefing"
  duration: "7d"
  type: ban

bug-abuse:
  display: "Bug / Exploit abuse"
  duration: "7d"
  type: ban

inappropriate:
  display: "Inappropriate behaviour"
  type: warn

ban-evasion:
  display: "Ban evasion"
  duration: "perm"
  type: ban
web.yml
# ─────────────────────────────────────────────────────────────
#  FluxBans — Web Server Configuration
# ─────────────────────────────────────────────────────────────

web:
  enabled: true

  # IP to bind to. Use 0.0.0.0 for all interfaces.
  bind: "0.0.0.0"

  port: 8080

  # Base URL used to generate links shown to players in kick messages.
  base-url: "http://example.com:8080"

  # ── SSL / HTTPS ──────────────────────────────────────────────
  ssl:
    enabled: false
    keystore-path: "ssl/keystore.jks"
    keystore-password: "changeme"
    port: 8443

  # ── Admin panel ───────────────────────────────────────────────
  admin:
    # Change this to something secure before going live.
    token: "CHANGE_THIS_SECRET_TOKEN"
    session-timeout: 60
    # Restrict admin panel access to specific IPs (empty = allow all)
    allowed-ips: []

  # ── Rate limiting ─────────────────────────────────────────────
  rate-limit:
    appeals-per-hour: 3
    searches-per-minute: 30

  # ── Theme and branding ────────────────────────────────────────
  theme:
    mode: dark           # "dark" or "light"
    server-name: "My Minecraft Server"
    accent-color: "e74c3c"
    server-description: ""
    server-ip: ""
    logo-url: ""
    discord-url: ""
    website-url: ""

  # ── Privacy ──────────────────────────────────────────────────
  privacy:
    anonymise-ips: true
    public-appeal-form: true

  entries-per-page: 20

  # ── SEO ──────────────────────────────────────────────────────
  seo:
    description: "View active bans, mutes, and submit appeals for our Minecraft server."
    keywords: "minecraft ban list, mute list, ban appeal, punishment history"
    allow-indexing: true
    og-image: ""
    twitter-site: ""
webhooks.yml
# ─────────────────────────────────────────────────────────────
#  FluxBans — Webhook Configuration
#
#  Supported types: discord | generic
#
#  Available events:
#    ban, unban, mute, unmute, kick, warn,
#    appeal_new, appeal_resolved
# ─────────────────────────────────────────────────────────────

webhooks:
  - url: "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN"
    type: discord
    enabled: false
    events:
      - ban
      - unban
      - mute
      - unmute
      - kick
      - warn
      - appeal_new
      - appeal_resolved
    # If true, silent punishments will NOT fire this webhook
    skip-silent: true
    colors:
      ban: 15158332        # red
      unban: 3066993       # green
      mute: 15105570       # orange
      unmute: 3447003      # blue
      kick: 10181046       # purple
      warn: 16776960       # yellow
      appeal_new: 3447003  # blue
      appeal_resolved: 3066993

  - url: "https://your-site.com/api/fluxbans-webhook"
    type: generic
    enabled: false
    events:
      - appeal_new
      - appeal_resolved
    # Optional — signs each request with X-FluxBans-Signature: sha256=<hex>
    secret: ""

/fluxbans command

The main admin command. Requires fluxbans.admin.

/fluxbans reload          Reloads all config files without restarting
/fluxbans import <plugin> Imports data from another plugin's database
/fluxbans debug           Prints version, database status and active connections

Requirements

Java 8 or newer. SQLite is bundled so there's no database server needed for a single server setup. ProtectCord, LuckPerms and Vault are all optional and get picked up automatically if they're present.


Live stats

bStats

FluxBans collects anonymous usage statistics via bStats. You can opt out in plugins/bStats/config.yml.

Project members

protectcord

Member


Technical information

License
MIT
Project ID