{"record":{"id":"e36af98375474f74","repo":"alibaba/nacos","slug":"pageno-and-pagesize-must-be-greater-than-zero-e36af9","errorCode":null,"errorMessage":"pageNo and pageSize must be greater than zero","messagePattern":"pageNo and pageSize must be greater than zero","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/persistence/extrnal/AuthExternalPaginationHelperImpl.java","lineNumber":72,"sourceCode":"     * @param args         query parameters\n     * @param pageNo       page number\n     * @param pageSize     page size\n     * @param rowMapper    {@link RowMapper}\n     * @return Paginated data {@code <E>}\n     */\n    @Override\n    public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,\n        final Object[] args,\n        final int pageNo, final int pageSize, final RowMapper rowMapper) {\n        return fetchPage(sqlCountRows, sqlFetchRows, args, pageNo, pageSize, null, rowMapper);\n    }\n    \n    @Override\n    public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows, Object[] args,\n        final int pageNo,\n        final int pageSize, final Long lastMaxId, final RowMapper rowMapper) {\n        if (pageNo <= 0 || pageSize <= 0) {\n            throw new IllegalArgumentException(\"pageNo and pageSize must be greater than zero\");\n        }\n        \n        // Query the total number of current records.\n        Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, args, Integer.class);\n        if (rowCountInt == null) {\n            throw new IllegalArgumentException(\"fetchPageLimit error\");\n        }\n        \n        // Compute pages count\n        int pageCount = rowCountInt / pageSize;\n        if (rowCountInt > pageSize * pageCount) {\n            pageCount++;\n        }\n        \n        // Create Page object\n        final Page<E> page = new Page<>();\n        page.setPageNumber(pageNo);\n        page.setPagesAvailable(pageCount);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/persistence/extrnal/AuthExternalPaginationHelperImpl.java#L54-L90","documentation":"Thrown by AuthExternalPaginationHelperImpl.fetchPage (the external MySQL/PostgreSQL variant) when pageNo or pageSize is <= 0. Identical validation logic to the embedded variant, but delegates to Spring's JdbcTemplate for external databases. Used when Nacos is configured to use MySQL or PostgreSQL instead of embedded Derby.","triggerScenarios":"An admin auth listing endpoint (users, roles, permissions) calls fetchPage with non-positive pagination values while Nacos is backed by an external database. The guard fires before the count query is sent to the external DB.","commonSituations":"Frontend pagination initialized at 0; API client omits pagination params defaulting to 0; a REST controller forwards raw query string values without validation; test harness uses 0-based page indexing.","solutions":["Ensure pageNo >= 1 and pageSize >= 1 in all paginated API requests.","Add controller-level validation or form-level defaults to guarantee positive pagination values.","Default missing pagination parameters to pageNo=1, pageSize=20."],"exampleFix":"// before\n@RequestParam(defaultValue = \"0\") int pageNo,\n@RequestParam(defaultValue = \"0\") int pageSize\npaginationHelper.fetchPage(countSql, fetchSql, args, pageNo, pageSize, mapper);\n\n// after\n@RequestParam(defaultValue = \"1\") int pageNo,\n@RequestParam(defaultValue = \"20\") int pageSize\npaginationHelper.fetchPage(countSql, fetchSql, args, pageNo, pageSize, mapper);","handlingStrategy":"validation","validationCode":"// Validate pagination before calling external DB fetchPage\nif (pageNo <= 0 || pageSize <= 0) {\n    throw new IllegalArgumentException(\"pageNo and pageSize must be >= 1\");\n}\nPage<E> page = paginationHelper.fetchPage(countSql, fetchSql, args, pageNo, pageSize, mapper);","typeGuard":"public static boolean isValidPagination(int pageNo, int pageSize) {\n    return pageNo > 0 && pageSize > 0;\n}","tryCatchPattern":"try {\n    Page<E> page = paginationHelper.fetchPage(countSql, fetchSql, args, pageNo, pageSize, mapper);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"pageNo and pageSize\")) {\n        return ResponseEntity.badRequest().body(\"Invalid pagination parameters\");\n    }\n    throw e;\n}","preventionTips":["Default pageNo to 1 (not 0) in all REST controllers and API clients.","Use @Min(1) validation annotations on pagination form fields.","Document 1-based page indexing for all Nacos API consumers."],"tags":["pagination","external-db","auth-plugin","input-validation","mysql","postgresql"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}