This is an automated email from the ASF dual-hosted git repository.

pankajkumar pushed a commit to branch branch-2.6
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.6 by this push:
     new b1927e6f7d5 HBASE-29955 HMaster getting aborted due to NPE while 
creating snapshot for invalid table name (#7852)
b1927e6f7d5 is described below

commit b1927e6f7d5c938d57ad4ffea465757477b626de
Author: Pankaj <[email protected]>
AuthorDate: Fri Mar 13 10:02:01 2026 +0530

    HBASE-29955 HMaster getting aborted due to NPE while creating snapshot for 
invalid table name (#7852)
    
    Signed-off-by: Duo Zhang <[email protected]>
    Signed-off-by: Nihal Jain <[email protected]>
    Signed-off-by: Peng Lu <[email protected]>
    Signed-off-by: Xiao Liu <[email protected]>
    Reviewed-by: Vaibhav Joshi <[email protected]>
    (cherry picked from commit fd9b0b22423c02c17c357b9e7a796285f4c9d208)
---
 .../hbase/master/snapshot/SnapshotManager.java     |  5 +--
 .../hbase/client/SnapshotWithAclTestBase.java      | 41 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java
index bb64062cf1b..def20b9132b 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java
@@ -720,8 +720,7 @@ public class SnapshotManager extends MasterProcedureManager 
implements Stoppable
       .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(master, 
nonceGroup, nonce) {
         @Override
         protected void run() throws IOException {
-          TableDescriptor tableDescriptor =
-            
master.getTableDescriptors().get(TableName.valueOf(snapshot.getTable()));
+          TableDescriptor tableDescriptor = 
sanityCheckBeforeSnapshot(snapshot, false);
           MasterCoprocessorHost cpHost = 
getMaster().getMasterCoprocessorHost();
           User user = RpcServer.getRequestUser().orElse(null);
           org.apache.hadoop.hbase.client.SnapshotDescription snapshotDesc =
@@ -731,8 +730,6 @@ public class SnapshotManager extends MasterProcedureManager 
implements Stoppable
             cpHost.preSnapshot(snapshotDesc, tableDescriptor, user);
           }
 
-          sanityCheckBeforeSnapshot(snapshot, false);
-
           long procId = submitProcedure(new SnapshotProcedure(
             getMaster().getMasterProcedureExecutor().getEnvironment(), 
snapshot));
 
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
index 8f8fdae22ea..4dc348548e5 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
@@ -20,6 +20,8 @@ package org.apache.hadoop.hbase.client;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.util.List;
@@ -32,6 +34,7 @@ import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.TableNameTestRule;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
 import org.apache.hadoop.hbase.security.User;
@@ -40,17 +43,23 @@ import 
org.apache.hadoop.hbase.security.access.AccessController;
 import org.apache.hadoop.hbase.security.access.Permission;
 import org.apache.hadoop.hbase.security.access.PermissionStorage;
 import org.apache.hadoop.hbase.security.access.SecureTestUtil;
+import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
+import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException;
 import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
 
 public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
 
+  @Rule
+  public TableNameTestRule name = new TableNameTestRule();
+
   private TableName TEST_TABLE = 
TableName.valueOf(TEST_UTIL.getRandomUUID().toString());
 
   private static final int ROW_COUNT = 30000;
@@ -309,4 +318,36 @@ public abstract class SnapshotWithAclTestBase extends 
SecureTestUtil {
       TEST_UTIL.getAdmin().listSnapshots(Pattern.compile(testSnapshotName));
     assertEquals(0, snapshotsAfterDelete.size());
   }
+
+  @Test
+  public void testCreateSnapshotWithNonExistingTable() throws Exception {
+    final TableName tableName = name.getTableName();
+    String snapshotName = tableName.getNameAsString() + "snap1";
+
+    try {
+      // Create snapshot without creating table
+      assertThrows("Snapshot operation should fail, table doesn't exist",
+        SnapshotCreationException.class,
+        () -> TEST_UTIL.getAdmin().snapshot(snapshotName, tableName));
+
+      // Create the table
+      TableDescriptor htd = 
TableDescriptorBuilder.newBuilder(tableName).build();
+      TEST_UTIL.createTable(htd, new byte[][] { TEST_FAMILY }, 
TEST_UTIL.getConfiguration());
+      try {
+        TEST_UTIL.getAdmin().snapshot(snapshotName, tableName);
+      } catch (Exception e) {
+        fail("Snapshot should have been created successfully");
+      }
+      assertTrue(TEST_UTIL.getAdmin().listSnapshots().stream()
+        .anyMatch(name -> name.getName().equals(snapshotName)));
+    } finally {
+      try {
+        TEST_UTIL.getAdmin().deleteSnapshot(snapshotName);
+      } catch (SnapshotDoesNotExistException e) {
+      }
+      if (TEST_UTIL.getAdmin().tableExists(tableName)) {
+        TEST_UTIL.deleteTable(tableName);
+      }
+    }
+  }
 }

Reply via email to