From bc55c67d798f6420668913314de706b2a52984f8 Mon Sep 17 00:00:00 2001 From: Wouter Gritter Date: Tue, 2 Jun 2026 13:19:05 +0200 Subject: [PATCH 1/2] Reduce default `read-timeout` to `25000` --- .../velocitypowered/proxy/config/VelocityConfiguration.java | 4 ++-- proxy/src/main/resources/default-velocity.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java index 2c7826e019..47fc44131e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -757,7 +757,7 @@ private static class Advanced { @Expose private int connectionTimeout = 5000; @Expose - private int readTimeout = 30000; + private int readTimeout = 25000; @Expose private boolean proxyProtocol = false; @Expose @@ -798,7 +798,7 @@ private Advanced(CommentedConfig config) { this.compressionLevel = config.getIntOrElse("compression-level", -1); this.loginRatelimit = config.getIntOrElse("login-ratelimit", 3000); this.connectionTimeout = config.getIntOrElse("connection-timeout", 5000); - this.readTimeout = config.getIntOrElse("read-timeout", 30000); + this.readTimeout = config.getIntOrElse("read-timeout", 25000); if (config.contains("haproxy-protocol")) { this.proxyProtocol = config.getOrElse("haproxy-protocol", false); } else { diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml index 0eae2734a3..d5cecfc998 100644 --- a/proxy/src/main/resources/default-velocity.toml +++ b/proxy/src/main/resources/default-velocity.toml @@ -127,8 +127,8 @@ login-ratelimit = 3000 # Specify a custom timeout for connection timeouts here. The default is five seconds. connection-timeout = 5000 -# Specify a read timeout for connections here. The default is 30 seconds. -read-timeout = 30000 +# Specify a read timeout for connections here. The default is 25 seconds. +read-timeout = 25000 # Enables compatibility with HAProxy's PROXY protocol. If you don't know what this is for, then # don't enable it. From 7b4bd7879d8976de7de5dd227f2822674c406c97 Mon Sep 17 00:00:00 2001 From: Wouter Gritter Date: Tue, 2 Jun 2026 13:19:47 +0200 Subject: [PATCH 2/2] Add migration reducing default `read-timeout` to `25000` --- .../proxy/config/VelocityConfiguration.java | 4 +- .../migration/ConfigurationMigration.java | 3 +- .../migration/ReadTimeoutMigration.java | 53 +++++++++++++++++++ .../src/main/resources/default-velocity.toml | 2 +- 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/config/migration/ReadTimeoutMigration.java diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java index 47fc44131e..e66f4662ef 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -32,6 +32,7 @@ import com.velocitypowered.proxy.config.migration.MiniMessageTranslationsMigration; import com.velocitypowered.proxy.config.migration.MotdMigration; import com.velocitypowered.proxy.config.migration.PacketLimiterMigration; +import com.velocitypowered.proxy.config.migration.ReadTimeoutMigration; import com.velocitypowered.proxy.config.migration.TransferIntegrationMigration; import com.velocitypowered.proxy.util.AddressUtil; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -513,7 +514,8 @@ public static VelocityConfiguration read(Path path) throws IOException { new MotdMigration(), new MiniMessageTranslationsMigration(), new TransferIntegrationMigration(), - new PacketLimiterMigration() + new PacketLimiterMigration(), + new ReadTimeoutMigration() }; for (final ConfigurationMigration migration : migrations) { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ConfigurationMigration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ConfigurationMigration.java index 7c00b7bbb6..7aa1269e0e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ConfigurationMigration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ConfigurationMigration.java @@ -30,7 +30,8 @@ public sealed interface ConfigurationMigration MotdMigration, MiniMessageTranslationsMigration, TransferIntegrationMigration, - PacketLimiterMigration { + PacketLimiterMigration, + ReadTimeoutMigration { boolean shouldMigrate(CommentedFileConfig config); void migrate(CommentedFileConfig config, Logger logger) throws IOException; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ReadTimeoutMigration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ReadTimeoutMigration.java new file mode 100644 index 0000000000..7eff6193e9 --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/migration/ReadTimeoutMigration.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018-2026 Velocity Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.velocitypowered.proxy.config.migration; + +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import org.apache.logging.log4j.Logger; + +/** + * The old default value of 30 seconds was causing the client to time-out on itself, + * fully disconnecting itself from the proxy instead of Velocity handling a graceful + * transfer/disconnect. + * + *

See PaperMC/Velocity#1819. + */ +public final class ReadTimeoutMigration implements ConfigurationMigration { + + private static final int PREVIOUS_DEFAULT_VALUE = 30_000; + private static final int NEW_DEFAULT_VALUE = 25_000; + + @Override + public boolean shouldMigrate(CommentedFileConfig config) { + return configVersion(config) < 2.9; + } + + @Override + public void migrate(CommentedFileConfig config, Logger logger) { + Integer current = config.get("advanced.read-timeout"); + if (current != null && current == PREVIOUS_DEFAULT_VALUE) { + // Only override value if it hasn't been changed. + config.set("advanced.read-timeout", NEW_DEFAULT_VALUE); + } + + config.setComment("advanced.read-timeout", + " Specify a read timeout for connections here. The default is 25 seconds."); + + config.set("config-version", "2.9"); + } +} diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml index d5cecfc998..a48a9436e4 100644 --- a/proxy/src/main/resources/default-velocity.toml +++ b/proxy/src/main/resources/default-velocity.toml @@ -1,5 +1,5 @@ # Config version. Do not change this -config-version = "2.8" +config-version = "2.9" # What port should the proxy be bound to? By default, we'll bind to all addresses on port 25565. bind = "0.0.0.0:25565"