Index: src/wp-includes/ms-functions.php
===================================================================
--- src/wp-includes/ms-functions.php	(revision 40588)
+++ src/wp-includes/ms-functions.php	(working copy)
@@ -577,8 +577,18 @@
 	if ( in_array( $blogname, $illegal_names ) )
 		$errors->add('blogname',  __( 'That name is not allowed.' ) );
 
-	if ( strlen( $blogname ) < 4 ) {
-		$errors->add('blogname',  __( 'Site name must be at least 4 characters.' ) );
+	/**
+	 * Filters the minimum site name length required when validating a site signup.
+	 *
+	 * @since 4.8.0
+	 *
+	 * @param int $length The minimum site name length. Default 4.
+	 */
+	$minimum_site_name_length = apply_filters( 'minimum_site_name_length', 4 );
+
+	if ( strlen( $blogname ) < $minimum_site_name_length ) {
+		/* translators: %s: minimum site name length */
+		$errors->add( 'blogname', sprintf( _n( 'Site name must be at least %s character.', 'Site name must be at least %s characters.', $minimum_site_name_length ), number_format_i18n( $minimum_site_name_length ) ) );
 	}
 
 	// do not allow users to create a blog that conflicts with a page on the main blog.
Index: tests/phpunit/tests/multisite/wpmuValidateBlogSignup.php
===================================================================
--- tests/phpunit/tests/multisite/wpmuValidateBlogSignup.php	(revision 40588)
+++ tests/phpunit/tests/multisite/wpmuValidateBlogSignup.php	(working copy)
@@ -14,6 +14,8 @@
 	protected static $existing_blog_name = 'existingsitefoo';
 	protected static $existing_blog_id;
 
+	protected $minimum_site_name_length = 4;
+
 	public static function wpSetUpBeforeClass( $factory ) {
 		self::$super_admin_id = $factory->user->create();
 		grant_super_admin( self::$super_admin_id );
@@ -86,6 +88,42 @@
 		$result = wpmu_validate_blog_signup( self::$existing_user_login, 'Foo Site Title', get_userdata( self::$existing_user_id ) );
 		$this->assertEmpty( $result['errors']->get_error_codes() );
 	}
+
+	/**
+	 * @ticket 39676
+	 *
+	 * @dataProvider data_filter_minimum_site_name_length
+	 */
+	public function test_filter_minimum_site_name_length( $site_name, $minimum_length, $expect_error ) {
+		$this->minimum_site_name_length = $minimum_length;
+		add_filter( 'minimum_site_name_length', array( $this, 'filter_minimum_site_name_length' ) );
+
+		$result = wpmu_validate_blog_signup( $site_name, 'Site Title', get_userdata( self::$super_admin_id ) );
+
+		remove_filter( 'minimum_site_name_length', array( $this, 'filter_minimum_site_name_length' ) );
+		$this->minimum_site_name_length = 4;
+
+		if ( $expect_error ) {
+			$this->assertContains( 'blogname', $result['errors']->get_error_codes() );
+		} else {
+			$this->assertEmpty( $result['errors']->get_error_codes() );
+		}
+	}
+
+	public function data_filter_minimum_site_name_length() {
+		return array(
+			array( 'fooo', 5, true ),
+			array( 'foooo', 5, false ),
+			array( 'foo', 4, true ),
+			array( 'fooo', 4, false ),
+			array( 'fo', 3, true ),
+			array( 'foo', 3, false ),
+		);
+	}
+
+	public function filter_minimum_site_name_length() {
+		return $this->minimum_site_name_length;
+	}
 }
 
 endif;
