{"record":{"id":"6a4ae4297c5a511f","repo":"alibaba/canal","slug":"dir-can-not-read-write","errorCode":null,"errorMessage":"dir[{}] can not read/write","messagePattern":"dir\\[(.+?)\\] can not read/write","errorType":"validation","errorClass":"CanalMetaManagerException","httpStatus":null,"severity":"error","filePath":"meta/src/main/java/com/alibaba/otter/canal/meta/FileMixedMetaManager.java","lineNumber":69,"sourceCode":"    @SuppressWarnings(\"serial\")\n    private final Position           nullCursor   = new Position() {\n                                                  };\n    private long                     period       = 1000;                                               // 单位ms\n    private Set<ClientIdentity>      updateCursorTasks;\n\n    public void start() {\n        super.start();\n        Assert.notNull(dataDir);\n        if (!dataDir.exists()) {\n            try {\n                FileUtils.forceMkdir(dataDir);\n            } catch (IOException e) {\n                throw new CanalMetaManagerException(e);\n            }\n        }\n\n        if (!dataDir.canRead() || !dataDir.canWrite()) {\n            throw new CanalMetaManagerException(\"dir[\" + dataDir.getPath() + \"] can not read/write\");\n        }\n\n        dataFileCaches = MigrateMap.makeComputingMap(this::getDataFile);\n\n        executor = Executors.newScheduledThreadPool(1);\n        destinations = MigrateMap.makeComputingMap(this::loadClientIdentity);\n\n        cursors = MigrateMap.makeComputingMap(clientIdentity -> {\n            Position position = loadCursor(clientIdentity.getDestination(), clientIdentity);\n            if (position == null) {\n                return nullCursor; // 返回一个空对象标识，避免出现异常\n            } else {\n                return position;\n            }\n        });\n\n        updateCursorTasks = Collections.synchronizedSet(new HashSet<>());\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/meta/src/main/java/com/alibaba/otter/canal/meta/FileMixedMetaManager.java#L51-L87","documentation":"Thrown by FileMixedMetaManager.start when the configured dataDir either cannot be created or, after creation, lacks read/write permission for the Canal process user. This meta manager persists client identity/cursor data to files on disk, so an inaccessible directory blocks startup entirely.","triggerScenarios":"FileMixedMetaManager.start() runs during instance startup. It first tries FileUtils.forceMkdir(dataDir) (an IOException there throws CanalMetaManagerException wrapping it). If the dir exists/created but dataDir.canRead() or dataDir.canWrite() is false, it throws this exact message.","commonSituations":"canal.mq.flatMessage or the meta dataDir (canal.instance.global.meta.dir or similar) points at a path the canal user cannot write (owned by root, read-only mount, SELinux denial), or the parent path does not exist and mkdir lacks permission.","solutions":["Check the configured dataDir path in canal.properties/instance properties and confirm it resolves as intended.","Grant the Canal process user read+write (and traverse) permissions on that directory: chown/chmod as needed.","Ensure the parent path exists so forceMkdir does not fail, or point dataDir at a writable location (e.g. under /home/canal/canal-data).","If running in a container, confirm the mounted volume is writable and not read-only."],"exampleFix":"# before (read-only or root-owned)\ncanal.instance.global.meta.dir = /var/lib/canal\n\n# after (writable by canal user)\ncanal.instance.global.meta.dir = /home/canal/canal-data\n# plus: chown -R canal:canal /home/canal/canal-data","handlingStrategy":"validation","validationCode":"java.io.File dir = new java.io.File(dataDirPath);\nif (!dir.exists() && !dir.mkdirs()) throw new IllegalStateException(\"cannot create meta dir: \" + dir);\nif (!dir.canRead() || !dir.canWrite()) throw new IllegalStateException(\"meta dir not rw: \" + dir);","typeGuard":null,"tryCatchPattern":"try { metaManager.start(); }\ncatch (CanalMetaManagerException e) {\n    if (e.getMessage().contains(\"can not read/write\")) { fixPermissions(dataDirPath); metaManager.start(); }\n    else throw e;\n}","preventionTips":["Point the meta dataDir at a writable, owned location for the canal user.","Verify directory permissions in deployment scripts before starting Canal.","For containers, mount the data volume read-write."],"tags":["filesystem","permissions","meta","startup"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}